Hacker News new | past | comments | ask | show | jobs | submit login
Given/when - The Perl switch statement (transfixedbutnotdead.com)
37 points by prog on Jan 23, 2011 | hide | past | web | favorite | 22 comments

What is this, National Perl Appreciation Day or something? This is great!

Useless in practice for me; I write for CPAN, so I have to stay backward-compatible at least to 5.6. But a nice taste of what I'll start doing in 2015 or so.

Most of us draw the line around 5.8.6 or so, given that all major distributions include a Perl at least that new. In fact most of them are at 5.10+ now, with a few notable exceptions.

Really? Even 5.8.8 has some major bugs.

I would only aim to support 5.8.9, 5.10.1, and 5.12.2, and at this point I don't know of anyone still using 5.8, so I just stick with the two most modern versions.

When 5.14 is released, it will really be time to kiss 5.8 goodbye.

I don't like it when my CPAN tests fail - and there are some test rigs out there running on 5.6. In practice, this has actually only resulted in my rewriting code once in a part of a module that is standard in 5.8 but wasn't earlier (one of the Tie modules, I think), but still. Using a whole new control structure isn't something I'll be doing soon, no matter how attractive it is.

I don't like it when my CPAN tests fail - and there are some test rigs out there running on 5.6.

Anyone who hasn't upgraded Perl 5 in eight and a half years seems unlikely to install new software.

Put "use 5.010" in your Makefile.PL and you won't see the failures from older Perl installs.

Yes, because they won't be running there. Maybe you like to target one version back, but there's a lot of systems out there running old Perls, and I don't see why I shouldn't be writing for the largest audience possible.

I don't see why I shouldn't be writing for the largest audience possible

Could your audience also be limited by the fact that your modules are IRC bots and bindings to XML parsers that already have bindings? :)

Oh, snap, I guess you win that argument.

What? Nobody that uses 5.6 also knows about the CPAN.

I would draw the line at 5.10 for "serious production stuff" and 5.12 for anything else. If you can't use the second oldest version, you can write your own code.

Despite not knowing much Perl, seeing Given/When being used as executable code is beautiful.

It's almost like someone took Gherkin (the Cucumber BDD parser) and got it working inline.

It's almost like someone took Gherkin (the Cucumber BDD parser) and got it working inline

Almost but not quite. given/when originates from perl6 and has been in the spec from at least 2006 and probably a lot earlier [1]. Its also been part of perl5 since 5.10 (2007) [2].

I believe both of these predate Cucumber/Gherkin.


[1] http://web.archive.org/web/20061011073242/http://perlcabal.o...

[2] http://perldoc.perl.org/perl5100delta.html#Switch-and-Smart-...

I just checked the book Perl 6 Essentials (2003, sigh) and it has given / when already, looking very close to the current standard.

it has been a long time since I have done any Perl but it's always a pleasure like seeing a old friend!

Can someone explain why given/when is better than switch/case?

From the examples in the link, I don't see an essential difference or benefit to the developer.

given and when are actually separate constructs, useful individually. given sets the topic ($_) to its argument for the scope of the block, and when smartmatches its argument against the topic (in most cases, mostly when it looks like the argument is a single value). This means that you can use when in any construct with $_ set. The other common place I use this is with iteration.

    for (@hosts) {
        when (@special) {
        when (/primary/) {
        when (/standby/) {
        default {
As well, when uses a value-based comparison called 'smartmatch', so it's more than a simple equality test like switch/case in C. Smartmatching a scalar against a hash tests for 'exists $hash{$_}'. Smartmatching a scalar against an array does a grep, returning all the items in the array that smartmatch against the value. Smartmatching an array against an array does a recursive smartmatch against pairs of array values. You can also customize smartmatch behaviour for your own classes, by overriding the ~~ operator.

Check the 'perlsyn' man page for the full set of smartmatch behaviours for core types.

http://perldoc.perl.org/perlsyn.html#Smart-matching-in-detai... http://perldoc.perl.org/perlsyn.html#Switch-statements

I hope this answered your question.

given/when isn't a switch statement. given and when are two separate constructs that happen to work well together for switch-statement-style purposes.

given temporarily sets the topic($_) to an expression. when smart-matches against topic and executes some code (followed by an implicit "next") if the match is successful.

given can be used without when and vice-versa.

given is useful for situations where you need to perform several operations on the result of an expression but don't want to name it, or in some cases, for when you want to emphasize an operation instead of the operand. For example, instead of 'say (some-long-complicated-expression.with-lots-of-calls-and-operators).perl', 'say .perl given the-expression'.

when can be used in given, but it can also be used in CATCH blocks (where $_ is set to the exception), or in for loops or other blocks where you are taking $_ as a parameter.

As it says, the 'use Switch;' version is a source filter as opposed to a feature built directly into the interpreter. For those unfamiliar, a source filter is something that modifies the source code before it actually is interpreted, and you have to be very careful with source filters. If your source filter injects code that blows up, or just isn't careful to preserve things like line numbers, then it can be a mess trying to track down problems because the source that you're looking at isn't exactly the once that's being run.

One of the biggest differences from a C style switch/case is that you can use regular expressions and a few other niceties in each of the when() clauses. if you're comparing it to the older Switch module then the biggest difference is that you're not likely to want to shoot the author of the module. Switch being a source filter can be very dangerous (not because it's a security risk but because combining them can cause all kinds of heisenbugs)

Perhaps this is a better example of why it is better than the switch/case? http://news.ycombinator.com/item?id=1735590

Will 'while' be replaced with 'aslongas' ?

The switch statement isn't being replaced. Perl5 never had a switch statement. Perl6 implemented on as given/when instead of switch/case. The Perl6 switch statement was back-ported to Perl 5.10. The 'use Switch' example in the post was a 3rd party work-around to the lack of a switch statement in the language.

Beyond that, might as well make fun of any differences between languages or just devolve into bickering over indentation/coding style/which line the opening brace should go on/etc.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact