neniro has asked for the wisdom of the Perl Monks concerning the following question:

Dear fellow monks,

If I use map or grep I can pass a block to them. I'd like to put map or grep into a subroutine and want to pass the block as argument to this subroutine. Is this possible and how?
sub selected { my $arr_ref = shift; die "selected: need an arrayref" unless (ref $arr_ref eq "ARRAY"); return grep {($_ > 35)} @$arr_ref; }
In my snippet above the block is a fixed part of the grep statement. Is it possible to pass a block to the subroutine and use it within the grep statement?

neniro

Replies are listed 'Best First'.
Re: How to pass blocks to subroutines
by exussum0 (Vicar) on Jun 12, 2004 at 16:03 UTC
    [nirvana:~] sporty% !vi vi t.pl sub x(&) { my $a = shift; my @b = (1,2); map &{$a}, @b; } x { print $_ };
    Is this what you were looking for? The prototype forces the block to be a code block. This works too...
    sub x { my $a = shift; my @b = (1,2); map &{$a}, @b; } x sub { print $_ };

    Bart: God, Schmod. I want my monkey-man.

      That's it (prototype)! Thank you very much.

      neniro
Re: How to pass blocks to subroutines
by neniro (Priest) on Jun 12, 2004 at 17:07 UTC
    Anyway it doesn't work the way I expect it if i pass the block as argument to the function.
    ##!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @items = qw ( 12 19 35 37 48 98 25 ); print Dumper [&selected (sub {($_ > 35)}, \@items)]; print Dumper [&selected2 (\@items)]; exit; sub selected { my ($func, $arr_ref) = @_; return grep $func, @$arr_ref; } sub selected2 { my $arr_ref = shift; die "selected: need an arrayref" unless (ref $arr_ref eq "ARRAY"); return grep {($_ > 35)} @$arr_ref; }

      Almost there. You just need to dereference $func.

      Replace:

       return grep $func, @$arr_ref;

      ... with:

       return grep &$func, @$arr_ref;

      ($func is a reference, and so always true.)

      print "Just another Perl ${\(trickster and hacker)},"
      The Sidhekin proves Sidhe did it!

        Damn, thats an ugly error. Can't believe I missed it.