Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Journal of jjore (6662)

Friday July 24, 2009
03:34 PM

You'll miss composable functions

[ #39347 ]

In perl or almost any other functional language (I guess) you can combine functions together and the innards of one thing aren't going to affect the flow control of the other. Here's a simple bit of perl:

method trap (CodeRef $block) {
    $block->() }
    uffda(); # Called in Perl, not called in Ruby
}
 
method moo ( ... ) {
    trap( sub {
 
        # Early return because ...
        return ... if ...;
 
        ...
    } );
}

Writing the equivalent flow control in Ruby and I found out today that the return() calls go all the way through and past the wrapping "trap" function.

WTF? I don't think I understand how Ruby programmers put up with this. Maybe 1.9 is better about this.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • I don't have time to experiment myself, but is this the difference between a Block and a Proc again?

    • It's more-or-less the equivalent of: map { return; } @array The inline block returns to the previous position in the call stack, which is not the method the map was placed in, but the method above that.
    • Oops, yes. So I just learned that blocks aren't functions even though they syntactically look like them. Apparently this would have worked just fine if I'd passed a proc{} in and use .call on it instead.

      I'm not sure why Rubyists accept blocks the way they are.

      Heck, why do perlers except that map and grep's little lambdas don't treat return() properly?

  • With perl, a coderef is a subroutine, basically.  With rubies coderefs, they are more like perl's blocks:

    use feature ':5.10';
    sub foo {
       say 'beginning of foo';
       bar();
       say 'ending of foo';
    }

    sub bar {
       say 'beginning of bar';
       my @foo = grep { return } (1,2,3,4); # I'd say this should mean none
       say 'ending of bar';
    }

    foo();

    Note that the grep kills bar.
    --
    --fREW
    http://blog.afoolishmanifesto.com