Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Passing with $_ instead of @_ in anonymous subs

by blokhead (Monsignor)
on Oct 28, 2002 at 07:29 UTC ( [id://208459]=perlquestion: print w/replies, xml ) Need Help??

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

I have the following hypothetical class which uses blessed anonymous subs as objects. For now I realize that it does nothing I couldn't do with grep, but please bear with me as this is only a slimmed-down example for the sake of this node.
package BlessedSub; use base 'Exporter'; @EXPORT = qw/blessed_sub/; ## prototyped for convenience sub blessed_sub(&) { my $anonymous_sub = shift; bless $anonymous_sub, __PACKAGE__; } sub filter { my ($self, @items) = @_; ## check if all the items return succesfully for (@items) { return 0 unless $self->($_); } return 1; }
The blessed_sub sub is prototyped so I can remove the sub keyword on the arguments, like this:
my $obj = blessed_sub { $_[0] =~ /foo/ }; die unless $obj->filter(qw/foobar foobaz bazfoo barbaz barfoo/);
But I soon after writing many lines like these, I decided that if I were already using prototypes to make blessed_sub behave more like a builtin, why not make it even more like a builtin? Our neighborhood friendly builtins like map and grep use the $_ variable to grab their argument, not @_ and $_[0]. I noticed that my anonymous subs were being called from within a for loop, so I changed the calling code to this:
my $obj = blessed_sub { /foo/ }; ## now uses $_, not @_ die unless $obj->filter(qw/foobar foobaz bazfoo barbaz barfoo/);
..and it worked in exactly the same way. Now blessed_sub really looks and feels just like a builtin. I enjoy being able to shorten builtins that default to $_ when possible, and I think the readability increases anyway from replacing $_[0] with $_. But am I missing some dangerous consequences of using $_ here? I think it's pretty safe from within a for loop, but I want to make sure no bad things can happen.

Thanks for your comments,

blokhead

Replies are listed 'Best First'.
Re: Passing with $_ instead of @_ in anonymous subs
by stefp (Vicar) on Oct 28, 2002 at 09:05 UTC
    $_ is visible within your methods. All you have to add at the beginning of your method is:

    @items = ($_) unless @items;
    But you can't expect to behave so as to automagically modify $_ if you modify $_[0].

    -- stefp -- check out Nemo

Re: Passing with $_ instead of @_ in anonymous subs
by fruiture (Curate) on Oct 28, 2002 at 11:05 UTC

    It is OK because:

    for (@items) { return 0 unless $self->($_); }

    'for' localizes $_ correctly and therefor $_ is what you expect it to be. This is perfectly OK.

    How about this btw.:

    sub filter (&@){ my $sub = shift; for(@_){ return unless $sub->() } 1 } print +( filter {/foo/} qw/foobar foobar bazfoo/ ) ? 'y' : 'n' , "\n";
    --
    http://fruiture.de

Log In?
Username:
Password:

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

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

      No recent polls found