Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

How to avoid $_ in grep

by felipe (Initiate)
on Nov 13, 2007 at 20:33 UTC ( [id://650588]=perlquestion: print w/replies, xml ) Need Help??

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

Is there any way to name the $_ variable in grep?

For instance, in a foreach loop, we can use $_ like this:

foreach (@array) { dosomething($_); }

I can avoid by "naming" it, just like this:

foreach my $element (@array) { dosomething($element); }

Let's go to the point. In a grep statement, I have something like this:

my @array_2 = grep {$_->func eq 'TEST'} @array_1;

I would really like to name the $_ because I do scripts for biologists and sometimes they modify scripts and they always get lost with $_. Is there any simple way to accomplish this?

Thanks in advance.

Replies are listed 'Best First'.
Re: How to avoid $_ in grep
by GrandFather (Saint) on Nov 13, 2007 at 21:41 UTC

    The bottom line is $_ is Perl magic. No amount of waving wands, shaking them vigorously or banging them on the table top will dispel the underlying magic that is $_.

    Much subtle stuff happens with $_ in map, foreach and grep. A comment that describes any relevant and important magic in each case may be more useful to newcomers to the language than trying to paper over the good magic that $_ provides.


    Perl is environmentally friendly - it saves trees
Re: How to avoid $_ in grep
by gamache (Friar) on Nov 13, 2007 at 20:47 UTC
    If you want to name it $ARG, then stick use English; somewhere at the top of your code.

    Update: As mentioned below, use English qw( -no_match_vars ); is even better. The English docs explain why.

      Great advice, and might I add:

      use English qw( -no_match_vars );

      is an even better idea.

      perl -e 'split//,q{john hurl, pest caretaker}and(map{print @_[$_]}(joi +n(q{},map{sprintf(qq{%010u},$_)}(2**2*307*4993,5*101*641*5261,7*59*79 +*36997,13*17*71*45131,3**2*67*89*167*181))=~/\d{2}/g));'
        Ah, I didn't know this... those match variables are more trouble than they're worth! Thanks for the tip!
Re: How to avoid $_ in grep
by blahblahblah (Priest) on Nov 14, 2007 at 03:06 UTC
    I feel that all of the above suggestions, though good, missed your original point: "I do scripts for biologists ... and they always get lost with $_." If biologists can't understand $_, then keep your code simple for them. Don't use $_, and while you're at it avoid map & grep. It's not that much harder to write out a loop, but it can make a world of difference to someone who is only a novice in perl.

    Joe

      I'd agree with the above; also, maybe it is possible to put a thicker line between things that 'custom users' need or are allowed to change ?
      Maybe offering a distinct Config file, or separating the allowed/easy to change code in front of the scripts or even distinct modules ?

      If the users are really meant to tamper the very hearth of underlying algorithms and so, $_ would probably be the smallest difficulty to overcome.

      Maybe you can do yet another thing, as I'm just learning from the book I mention in the signature below:
      can you offer them some placeholder subs and use callbacks, so that they could easily manage their own particular code snippets within the otherwise bigger code machinery ?

      Krambambuli
      ---
      enjoying Mark Jason Dominus' Higher-Order Perl
      Thanks all for your replies. I have to say that, although blahblahblah didn't give me the solution I was looking for, he understood me perfectly and he came up with a nice solution. Thanks all. Problem solved: I won't use grep.
Re: How to avoid $_ in grep
by lupey (Monk) on Nov 13, 2007 at 21:00 UTC

    Would this work for you? Just take a reference to $_.

    my @array_2 = grep {my $element = \$_; $$element =~ /foo/} @array_1;

    lupey

      If you don't mind the usually small cost of copying,

      my @array_2 = grep { my $element = $_; $element->func() eq 'TEST' } @array_1;

      It's basically the same as my ($arg1, $arg2) = @_; in subs.

      If you're dealing with very long strings and want to avoid the cost of copying without having to deal with references, you can create an alias,

      my @array_2 = grep { our $element; local *element = \$_; $element->func() eq 'TEST' } @array_1;

      or

      use Data::Alias qw( alias ); my @array_2 = grep { alias my $element = $_; $element->func() eq 'TEST' } @array_1;

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-19 20:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found