Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^2: Programming in Perl without semicolon

by ikegami (Patriarch)
on Jan 31, 2009 at 03:00 UTC ( [id://740371]=note: print w/replies, xml ) Need Help??


in reply to Re: Programming in Perl without semicolon
in thread Programming in Perl without semicolon

Yuck! Use use vars.

{ use vars qw( @cache @n ) } {@cache = (0, 1)} sub fib { {push @n, shift} {return pop @n if $n[-1] < 2} {$cache [$n[-1]] ||= fib ($n[-1] - 1) + fib ($n[-1] - 2)} {return $cache[pop @n]} }

Bonus: Doesn't confine you to the main namespace!


Now if we could only localize variables, we wouldn't need to manage our own stack.

{ use vars qw( @cache ) } {@cache = (0, 1)} sub fib { (local (our $n = shift)) && do { {return $n if $n < 2} {$cache[$n] ||= fib ($n - 1) + fib ($n - 2)} {return $cache[$n]} } }

Bonus: Don't have to use use vars except for globals!


By the way, the body simplifies down to a single expression, and your cache initialiser is not needed.

{ use vars qw( @cache ) } sub fib { (local (our $n) = shift), ( $n < 2 ? $n : $cache[$n] ||= fib ($n - 1) + fib ($n - 2) ) }

Update: Replaced buggy
(local our $n = shift) && ...
with
(local (our $n) = shift) && ...

Replies are listed 'Best First'.
Re^3: Programming in Perl without semicolon
by JavaFan (Canon) on Jan 31, 2009 at 08:37 UTC
    Bonus: Doesn't confine you to the main namespace!
    That's only a bonus if you can switch packages without a semicolon. I haven't figured out how, except for the useless:
    {package Foo}
    (local our $n = shift) && do { ... }
    I'm surprised this works. I would have expected 'our' to be in effect after the statement, just like 'my'. (If you replace 'local our' with 'my', the code wouldn't compile under 'strict').

    Unfortunally, it's not a general technique. It works here because 'fib(0)' is supposed to return '0'; the block isn't executed if the argument of the function is 0.

      That's only a bonus if you can switch packages without a semicolon.

      Oh yeah. Well, no bonus, but it still makes it more readable.

      I'm surprised this works.

      Me too, but it makes sense. It allows for

      our $state = $next_states{$state};

      Unfortunally, it's not a general technique.

      Oops! Just replace the and op with a list op or replace the sassign op with an aassign op.

      (local our $n = shift), ...

      or

      (local (our $n) = shift) && ...

      The former is simpler. The latter has the advantage that it doesn't affect the return value in list context.

      Unfortunally, it's not a general technique. It works here because 'fib(0)' is supposed to return '0'; the block isn't executed if the argument of the function is 0.
      But it can be written as:
      local our ($n, $m) = (shift, 0)) && do { }
      and then it will always do the 'do'.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://740371]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (1)
As of 2024-04-25 00:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found