rjbs advises to avoid given/when

Having been liberated from Perl 5.8.8 only recently (and not completely, really), I've never used given/when. rjbs explains some gotchas.

From http://irclog.perlgeek.de/crimsonfu/2012-03-16#i_5305433

18:26 ironcamel   so you are at least using the perl 5.10 syntax candy?
18:26 pdurbin     maybe. i don't know :)
18:26 ironcamel   given/when, say, state, and //
18:26 pdurbin     nope
18:27 pdurbin     too fancy for me
18:27 * ironcamel bonks pdurbin on the head
18:27 ironcamel   you should at least look into given/when, it is amazing
18:27 ironcamel   it has "pattern matching"
18:28 ironcamel   only other language i know that has that is scala
18:28 ironcamel   it has nothing to do with regex patterns
18:28 ironcamel   and say "foo" is same thing as print "foo\n"
18:28 pdurbin     "You know, I actually advise people to avoid given/when" --rjbs 2011-04-28
18:28 ironcamel   don't listen to him
18:29 ironcamel   listen to everything else he says, just ignore that bit
18:29 pdurbin     heh
18:29 pdurbin     i should ask him if i can publish this email
18:30 pdurbin     or has he written about it extensively already?
18:30 ironcamel   he wrote you that in an email?
18:30 pdurbin     yeah
18:31 ironcamel   what were you emailing him about?
18:31 pdurbin     plus a long explanation i don't understand
18:32 pdurbin     something for shuff: Bug #64302 for Dist-Zilla: Requiring EU:MM 6.31 excludes RHEL5 - https://rt.cpan.org/Public/Bug/Display.html?id=64302
18:32 ironcamel   i wonder if he wrote that before 5.10.1 was released
18:32 ironcamel   because 5.10.0 had some issues with given/when that were fixed
18:32 pdurbin     he wrote it 2011-04-28

-------- Original Message --------
Subject: Re: Bug #64302 for Dist-Zilla: Requiring EU:MM 6.31 excludes RHEL5
Date: Fri, 16 Mar 2012 15:16:30 -0400
From: Ricardo Signes <rjbs@cpan.org>
To: Philip Durbin <philipdurbin@gmail.com>

* Philip Durbin <philipdurbin@gmail.com> [2012-03-16T15:11:54]
> i brought up your point about given/when today:
> http://irclog.perlgeek.de/crimsonfu/2012-03-16#i_5305433
>
> do you mind if I publish these emails on my perl blog?
Not at all, go ahead.  Thanks for asking first.

-- rjbs 

-------- Original Message --------
Subject: Re: Bug #64302 for Dist-Zilla: Requiring EU:MM 6.31 excludes RHEL5
Date: Thu, 28 Apr 2011 17:06:41 -0400
From: Ricardo Signes <rjbs@cpan.org>
To: Philip Durbin <philipdurbin@gmail.com>

* Philip Durbin <philipdurbin@gmail.com> [2011-04-28T17:02:00]
>> You know, I actually advise people to avoid given/when... but that's a
>> different kettle of fish.
> Hmm, no need to write up anything on my account, but if you're
> already blogged about it, please share a link.
There are two problems.  One is that when() topicalizes $_, like for, but it
topicalizes the *lexical* $_ rather than the *dynamic* $_ like for does.

So:

  my $x = 'foo';

  given ($x) {
    when (/f/) {
      try   { die 'bar' }
      catch { warn "exception: $_" }
    }
  }

This will warn "exception: bar" because the closure passed to catch has closed
over lexical $_ instead of using the global.  You could write $::_, but who
remembers this sort of detail?  It's come up a few times as a bug report to
Try::Tiny.  Of course, there are other ways around the bug as presented above,
but you can imagine how it will manifest as a category of bugs.

The other is that ~~, the smart match used to test the given against when
cases, is ridiculously complex.  It has something like 27 possible behaviors,
several of which can recurse to re-dispatch to the 27-way choice again.

I don't think Perl needed ~~.  It needed an "in" operator.  A "switch"
statement might have been nice, but the one we got is too complex.

-- rjbs

Update: I'm sorry for the formatting of this post. I'm not sure where to edit the css. For now there's a more readable version at http://paste.perldancer.org/1uYeL1Fi6M5sL

Also, there is more discussion here: http://irclog.perlgeek.de/crimsonfu/2012-03-16#i_5306245

4 Comments

using for / when instead of given / when removes at least one of the problems.

I have a much longer and detailed explanation at Use for() instead of given()

Good article. Lexical $_ and "smart" match rank with the version mess as disasters that weren't thought through, and can probably never be removed.

I forgot "each," "keys," and "values" working on arrays and array/hash references (well, sort-of working). This garbage apparently counts as language progress; it is why I develop for "perl 5.6 plus bug fixes," and ignore the shiny junk in newer "releases."

Leave a comment

About Philip Durbin

user-pic I blog about Perl.