Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Bring Out Your New Perl Code

by Limbic~Region (Chancellor)
on Dec 19, 2007 at 03:58 UTC ( #657784=perlmeditation: print w/replies, xml ) Need Help??

As you have already heard, Perl turned 20 today and Perl 5.10 has been released. While it is fun to see where Perl has been, I wanted to take an opportunity to see where it is going. I read through perldelta and came up with:
#!/usr/bin/perl use feature qw/say state switch/; use strict; use warnings; sub gen_cashier { my ($start) = @_; state $cash_in_store = $start // 0; return sub { my ($method, $amount) = @_; given ($method) { when (undef) { warn "Method name required\n" } when ('add') { $cash_in_store += $amount } when ('del') { $cash_in_store -= $amount } when ('bal') { return $cash_in_store } when (/^(?<name>[a-zA-Z]+)$/) { warn "$+{name} unimplement +ed\n" } default { warn "$method is illegal method name\n" } } }; } my @drawer = map gen_cashier, 1..4; $drawer[0]->(add => 59); $drawer[1]->(del => 17); $drawer[2]->(steal => 20); say $drawer[3]->('bal');
Granted, I just modified some Perl 6 I had previously written, but it was exciting. So what does your new code look like?

Cheers - L~R

Improved named capture example - thanks kyle

Replies are listed 'Best First'.
Re: Bring Out Your New Perl Code
by grinder (Bishop) on Dec 19, 2007 at 07:29 UTC

    Minor point: you can simplify your feature statement by just saying

    use 5.10;

    err, major point... you should pay attention to what ambrus says below.

    • another intruder with the mooring in the heart of the Perl

      That (use 5.10) will give an error, because it means to require perl version 5.100.000. Instead, say use 5.010; or use 5.010_000; or use 5.10.0; or use v5.10; or use v5.10.0;.

      (I've fallen to this trap yesterday when trying 5.10 out, but the error message is nice enough:

      Perl v5.100.0 required (did you mean v5.10.0?)--this is only v5.10.0, +stopped at -e line 1. BEGIN failed--compilation aborted at -e line 1.
Re: Bring Out Your New Perl Code
by ambrus (Abbot) on Dec 19, 2007 at 15:17 UTC
Re: Bring Out Your New Perl Code
by zby (Vicar) on Dec 19, 2007 at 09:27 UTC
    What does the 'state' declaration really do here? How does it make $cash_in_store different from a normal closured variable?

    Update: I analyzed it a bit - and I see it now - if $cash_in_store was not declared state then it would not be shared between $drower->[0], $drower->[1], $drower->[2] and $drower->[3]. But of course as a closured variable it still would work for individual drawers.

      It's the exact difference between the following two code snippets:

      BEGIN { my $var = 10; sub next { return ++$var; } }

      And the following:

      sub next { state $var = 10; return ++$var; }

      Now let's have a show of hands, how many people prefer the First Way To Do It? ... hmm, I see no hands? I thought as much :)

      Tip o' the hat to Roy Johnson for pointing out that it was a BEGIN block I wanted, not an lexical scope with a label BEGIN:. And you do need a BEGIN block, not a bare block, otherwise you can run into grief with uninitialised values (which is kind of the whole point).

      • another intruder with the mooring in the heart of the Perl

        Actually you should compare using a bare block (no BEGIN) which is the standard (older) way to have "state" variables.

        I like 'state' but the old way is still useful if you need a pair of cooperating subs (or more):

        % steph@ape (/home/stephan) % % cat state_old.px #!/usr/bin/perl+ { my $var = 10; sub next1 { ++$var; } sub next1_odd { if ($var % 2 == 0) { ++$var; } else { ++$var; ++$var; } } } $\ = qq{\n}; print next1() for 1..5; print next1_odd(); % steph@ape(/home/stephan) % % perl+ -w state_old.px 11 12 13 14 15 17
        cheers --stephan

      It looks like it acts more like a static variable in a C routine. There is no closure in Limbic~Region's code yet the variable looks like it is expected to retain its value between calls.

      90% of every Perl application is already written.
Re: Bring Out Your New Perl Code (humour)
by blazar (Canon) on Dec 29, 2007 at 23:07 UTC
    So what does your new code look like?

    I personally believe that I should first warn any newbie possibly reading this post in the future that its content is deliberately humorous in a sarcastic way. So please don't even think of picking up the code shown here and use it in anything serious...

    I... huh... personally believe that with 5.10's new features we can eventually implement in Perl the FOR-CASE paradigm:

    #!/usr/bin/perl use strict; use warnings; use 5.010; for my $count (0..4) { given ($count) { when (0) { say "Whoa, it's $count" } when (1) { say "Then it becomes $count" } when (2) { say "Then, $count" } when (3) { say "Only to further increase to $count" } when (4) { say "And eventualy stop at $count" } } }
    Of course, we may avoid the inner given:

    But we care about efficiency all the time, don't we? Furthermore, this may begin to give a wrong output the day a number which is equal to 0 will also be equal to 1, for example.

    Last, prior to 5.10, one of the standard answers for those in search of a switch statement was to use a dispatch table instead, so for backwards compatibility reasons, let's see how it may look like:

    Or at most, using closures:

    Anyway, with 5.10 it's much slicker!

    If you can't understand the incipit, then please check the IPB Campaign.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://657784]
Approved by kyle
Front-paged by derby
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2021-05-13 01:23 GMT
Find Nodes?
    Voting Booth?
    Perl 7 will be out ...

    Results (134 votes). Check out past polls.