Re: When does $_ get used?
by dragonchild (Archbishop) on Jul 26, 2001 at 21:35 UTC
|
You're confusing $_ with the return from shift. shift will assume @_ if it isn't given an argument, but it will not assign its return value to $_. None of the functions will ever assign their return value to @_ or $_. If there is no-one to receive the value, the return value is discarded.
Now, the reason that foreach(@array) works the way you think it does is because that's a property of foreach. while does not have this property. That may have been the piece of info you were missing. | [reply] |
(ichimunki) Re: When does $_ get used?
by ichimunki (Priest) on Jul 26, 2001 at 21:44 UTC
|
This is partly a scoping issue, but mostly a void context issue. Variables declared with a foreach have a scope lexical to the associated block and in this case $_ is implied by the absence of an iterator. The variables in your while condition have no such luck. If you perform a shift operation in a void context, Perl is not going to assign a value to $_ automatically.
#!/usr/bin/perl -w
use strict;
my @list = ( 1, 2, 3, 'foo', 4, 'bar' );
$_ = 1;
foreach (@list)
{
print "$_\n";
}
print "between loops: $_\n";
while (shift @list)
{
print "$_\n";
}
print "after loops: $_\n";
shift @list;
shift @list;
shift @list;
print "$_\n"; #we are expecting 3, but it's really 1.
UPDATE: IMPORTANT NOTE. One thing we didn't mention here is that each time you are shifting @list, you are destroying your list, so eventually the list is completely destroyed which will cause the while condition to evaluate false and stop the while loop. But since we've destroyed the loop the final 3 shifts are actually operating on an empty list! | [reply] [d/l] |
Re: When does $_ get used?
by wiz (Scribe) on Jul 26, 2001 at 21:50 UTC
|
$_ is used if a variable is used in the function. while (shift @array) tests whether shift @array is true. It doesn't go through the values of @array.
foreach (@array){} says go through each value of @array. $_ stands for the current element for each step in the foreach.
$_ is used if the function in question searches through the the values of an @array or keys %hash.
If it doens't search through the values, then it doesn't use $_.
----------------------------
Wiz, The VooDoo Doll
Head Master of 12:30 Productions
----------------------------
| [reply] [d/l] [select] |
|
|
I'm sorry I confused the issue. My question wasn't "why
doesn't while assign a value to $_"
but "why doesn't shift?"
Certainly while( <> ) { ... } works as I
expected it to. While talking it over with other helpful
monks via the Chatterbox, I found that the individual
functions will say if they use $_ in their
descriptions.
That being said, is there a good reason why
shift (for example) doesn't assign
a value to $_ unless another variable is
explicitly used?
| [reply] [d/l] [select] |
|
|
Because, for one thing, it's useful to call shift in void context to remove an array element with no other side-effects. Clobbering $_ in these cases would make it less useful.
| [reply] |
Re: When does $_ get used?
by mexnix (Pilgrim) on Jul 26, 2001 at 22:08 UTC
|
I didn't really get your question at first, but after reading the replies, esp. dragonchild, I understood what was going on. If you use while (my $elm = shift @list) { some_funct $elm } (or while ($_ = shift @list) {)that will work. I doubt, have no clue, that this is coding practice, but it works. All the other replies are good, this is just using while.
__________________________________________________
<moviequote name="The Whole Nine Yards">
Jimmy T: Oz, we're friends, friends do not engage in sexual congress with each others wives. </moviequote>
mexnix.perlmonk.org
| [reply] [d/l] [select] |
|
|
It is indeed bad coding practice, unless the following behaviour is actually desired:
| | | my @l = (1, 2, 3, 0, 5, 6);
while (my $x = shift @l) {
print "$x ";
}
## OUTPUT ##
1 2 3
|
The correct idiom is:
| | | my @l = (1, 2, 3, 0, 5, 6);
while (@l) {
my $x = shift @l;
print "$x ";
}
|
MeowChow
s aamecha.s a..a\u$&owag.print | [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
|
|
|
|
|
|
|
|
|