Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Noob trying to understand simple Perl grep statement

Reply
Thread Tools

Noob trying to understand simple Perl grep statement

 
 
walterbyrd
Guest
Posts: n/a
 
      12-02-2008
This is from the perl objects book.

my @required = qw(preserver sunscreen water_bottle jacket);
my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
for my $item (@required) {
unless (grep $item eq $_, @skipper) { # not found in list?
print "skipper is missing $item.\n";
}
}

I don't understand this line:

unless (grep $item eq $_, @skipper)

I understand that $item is each item in the @required array. I am
guessing that the @required array is what is being grep'd. But what is
$_ ? Is that also each item from the @required array? If so, why not
just use the $item variable again? And what does >>$_, @skipper<<
mean? What is with the comma? Is that supposed to mean: grep $item
@skipper?

Is this supposed to check if the skipper is missing any required item?
Why not:

unless (grep $item @required eq grep $item @skipper)

 
Reply With Quote
 
 
 
 
Willem
Guest
Posts: n/a
 
      12-02-2008
walterbyrd wrote:
) I don't understand this line:
)
) unless (grep $item eq $_, @skipper)

Let's break it into pieces then:

grep $item eq $_ , @skipper

grep <something> @skipper
Means: Return each item from @skipper for which <something> is true.

Furthermore, inside <something>, the variable $_ is the current item from
@skipper under consideration.

So:
grep $item eq $_ , @skipper

Means:
Return each item from @skipper for which >> $item eq $_ << is true.
Or in other words:
Return each item from @skipper that is equal to $item.

And the last bit is unless(), which means that the returned array is being
looked at as a truth value. An array is true if it contains elements.


Simple, huh ? Well, that's Perl for you.



SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Reply With Quote
 
 
 
 
Tad J McClellan
Guest
Posts: n/a
 
      12-02-2008
Willem <(E-Mail Removed)> wrote:
> walterbyrd wrote:
> ) I don't understand this line:
> )
> ) unless (grep $item eq $_, @skipper)


> And the last bit is unless(), which means that the returned array is being
> looked at



There is no returned array. There is not even a returned list.

There is only the return value from grep() in a scalar context.

perldoc -f grep

In scalar context, returns the number of times the expression was true.


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
 
Reply With Quote
 
Tad J McClellan
Guest
Posts: n/a
 
      12-02-2008
walterbyrd <(E-Mail Removed)> wrote:
> This is from the perl objects book.
>
> my @required = qw(preserver sunscreen water_bottle jacket);
> my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
> for my $item (@required) {
> unless (grep $item eq $_, @skipper) { # not found in list?
> print "skipper is missing $item.\n";
> }
> }
>
> I don't understand this line:
>
> unless (grep $item eq $_, @skipper)
>
> I understand that $item is each item in the @required array. I am
> guessing that the @required array is what is being grep'd.



No, the @skipper array is what is being grep'd.


> But what is
> $_ ?



One of the elements from the @skipper array.


> And what does >>$_, @skipper<<
> mean? What is with the comma?



That is the syntax for calling grep:

perldoc -f grep

=item grep EXPR,LIST

It says that a comma is required after the expression.

(The expression for grep() is the "$item eq $_" part above).


> Is that supposed to mean: grep $item
> @skipper?



No, because that would be a syntax error.


> unless (grep $item @required eq grep $item @skipper)



More syntax errors...


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      12-02-2008
walterbyrd wrote:
> This is from the perl objects book.
>
> my @required = qw(preserver sunscreen water_bottle jacket);
> my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
> for my $item (@required) {
> unless (grep $item eq $_, @skipper) { # not found in list?
> print "skipper is missing $item.\n";
> }
> }


That can also be written as:

my @required = qw(preserver sunscreen water_bottle jacket);
my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
for my $item (@required) {
my $count;
for $_ (@skipper) {
$count++ if $item eq $_;
}
unless ($count) { # not found in list?
print "skipper is missing $item.\n";
}
}

> I don't understand this line:
>
> unless (grep $item eq $_, @skipper)
>
> I understand that $item is each item in the @required array. I am
> guessing that the @required array is what is being grep'd.


No, the @skipper array is being grep'd.

> But what is $_ ?


The value of the elements of @skipper.

> Is that also each item from the @required array? If so, why not
> just use the $item variable again? And what does >>$_, @skipper<<
> mean? What is with the comma? Is that supposed to mean: grep $item
> @skipper?


perldoc -f grep

grep EXPR,LIST

> Is this supposed to check if the skipper is missing any required item?
> Why not:
>
> unless (grep $item @required eq grep $item @skipper)


Because Perl does not work that way.



John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
 
Reply With Quote
 
xhoster@gmail.com
Guest
Posts: n/a
 
      12-02-2008
walterbyrd <(E-Mail Removed)> wrote:
> This is from the perl objects book.
>
> my @required = qw(preserver sunscreen water_bottle jacket);
> my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
> for my $item (@required) {
> unless (grep $item eq $_, @skipper) { # not found in list?
> print "skipper is missing $item.\n";
> }
> }


This would probably best be done with a hash rather than an array for at
least one of those structures.

>
> I don't understand this line:
>
> unless (grep $item eq $_, @skipper)
>
> I understand that $item is each item in the @required array. I am
> guessing that the @required array is what is being grep'd.


@skipper is what is being grepped. One time for each thing in @required

> But what is
> $_ ? Is that also each item from the @required array?


In the grep, $_ is set to each thing in the @skipper array in turn.

> If so, why not
> just use the $item variable again? And what does >>$_, @skipper<<
> mean?


In this context, nothing. You broken down the code incorrectly. The
grouping is
($item eq $_), @skipper
not
$item eq ($_,skipper)

Where the parentheses are meta language that indicate grouping for our
discussion, not necessarily to be taken as literal Perl syntax.


> What is with the comma? Is that supposed to mean: grep $item
> @skipper?


No, it means (about) the same thing as:

grep {$item eq $_} @skipper.

You provide grep with either a block with no comma, then a list; or an
expression then comma then a list. That is just how grep works.

See perldoc -f grep:

grep BLOCK LIST
grep EXPR,LIST



> Is this supposed to check if the skipper is missing any required item?


The overall code, yes. The grep part of the code just return a count
(Because it is invoked in a scalar context) of the things in @skipper which
equal whatever happens to be in $item at the moment. if the contents of
@skipper is unique, then this count will either be 0 (considered false) or
1 (considered true)

> Why not:
>
> unless (grep $item @required eq grep $item @skipper)


Because that wouldn't work. It is a syntax error at several levels,
and semantic error at several more.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
Reply With Quote
 
J.D. Baldwin
Guest
Posts: n/a
 
      12-02-2008

In the previous article, walterbyrd <(E-Mail Removed)> wrote:
> This is from the perl objects book.
>
> my @required = qw(preserver sunscreen water_bottle jacket);
> my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
> for my $item (@required) {
> unless (grep $item eq $_, @skipper) { # not found in list?
> print "skipper is missing $item.\n";
> }
> }
>
> I don't understand this line:
>
> unless (grep $item eq $_, @skipper)
>
> I understand that $item is each item in the @required array. I am
> guessing that the @required array is what is being grep'd. But what
> is $_ ? Is that also each item from the @required array? If so, why
> not just use the $item variable again? And what does >>$_,
> @skipper<< mean? What is with the comma? Is that supposed to mean:
> grep $item @skipper?


grep is taking two arguments, separated by the comma. They are:

1. $item eq $_

and

2. @skipper

The effect of this is to go through elements of @skipper, creating a
list out of the ones that equal $item (i.e., when the first arg
evaluates to "true." For any given $item, there will be only one
matching element (assuming items in @skipper are unique).

So, when $item is a member of @skipper, the grep will return a
one-element list consisting of that item. When $item is not found in
@skipper, the grep will return an empty list.

In the latter case, when grep returns an empty list, it will trigger
the block after the unless, printing the value of $item.

> Is this supposed to check if the skipper is missing any required item?
> Why not:
>
> unless (grep $item @required eq grep $item @skipper)


OK, first off, grep requires a comma or a block to be syntactically
correct.

Second, the first argument of grep is a truth-test, which determines
whether each given element of the array argument is passed into the
result list. If $item is non-null, then

grep $item, @required

will just be the same as @required (since $item is always true for a
non-empty string).

A revised version of your line:

unless (grep $item, @required eq grep $item, @skipper)

still has problems because the expression will be true if @required
and @skipper evaluate to the same value in scalar context. Probably
not what you intended.
--
_+_ From the catapult of |If anyone objects to any statement I make, I am
_|70|___=}- J.D. Baldwin |quite prepared not only to retract it, but also
\ / http://www.velocityreviews.com/forums/(E-Mail Removed)|to deny under oath that I ever made it.-T. Lehrer
***~~~~----------------------------------------------------------------------
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      12-02-2008
walterbyrd <(E-Mail Removed)> wrote:
>This is from the perl objects book.
>
>my @required = qw(preserver sunscreen water_bottle jacket);
>my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
>for my $item (@required) {
> unless (grep $item eq $_, @skipper) { # not found in list?
> print "skipper is missing $item.\n";
> }
>}
>
>I don't understand this line:
>
> unless (grep $item eq $_, @skipper)
>
>I understand that $item is each item in the @required array.


Correct.

> I am
>guessing that the @required array is what is being grep'd.


Wrong. It is the @skipper array, that is filtered. After all, that is
the one, that is passed as argument to grep.

>But what is
>$_ ? Is that also each item from the @required array?


No, it is subsequently set to each element of @skipper to test if $item
is equal to that element.

>If so, why not
>just use the $item variable again? And what does >>$_, @skipper<<
>mean? What is with the comma?


You are reading it wrong, adding some parenthesis to make the precedence
clearer:
grep ( {$item eq $_},
@skipper);

jue
 
Reply With Quote
 
Tad J McClellan
Guest
Posts: n/a
 
      12-02-2008
J.D. Baldwin <(E-Mail Removed)> wrote:

> If $item is non-null, then
>
> grep $item, @required
>
> will just be the same as @required (since $item is always true for a
> non-empty string).



$item = '0'; # a non-empty string that is NOT true...


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
 
Reply With Quote
 
Tad J McClellan
Guest
Posts: n/a
 
      12-02-2008
Jürgen Exner <(E-Mail Removed)> wrote:
> walterbyrd <(E-Mail Removed)> wrote:


> You are reading it wrong,



writing it wrong will probably not help...


> adding some parenthesis to make the precedence
> clearer:
> grep ( {$item eq $_},

^
^
> @skipper);



grep ( {$item eq $_} # grep BLOCK LIST
@skipper);

or

grep ( $item eq $_, # grep EXPR,LIST
@skipper);


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Trying to understand a very simple class - from the book "dive intopython" walterbyrd Python 5 05-21-2009 03:35 AM
Here a noob, there a noob.... JimDoire MCSE 0 04-10-2008 07:23 PM
Noob: What is a slot? Me trying to understand another's code Carnell, James E Python 2 09-05-2007 03:15 PM
Please help Perl Newbie understand this statement jm-1@remotekontrol.com Perl Misc 10 06-27-2006 09:36 AM
noob: Trying perl, and decoding MIME attachments..stuck in my code..can someone take a look? cayenne Perl Misc 3 05-26-2004 05:19 PM



Advertisments