Re: ARGV question
by betterworld (Curate) on Aug 18, 2008 at 21:11 UTC
|
$verbose will be "-v" if "-v" is the first thing in @ARGV. This is because "&&" always returns the right operand if the left operand is true. In this case, it returns the result of shift. | [reply] [d/l] [select] |
|
| [reply] |
|
You are pretty close in your description, but not quite right. I can't think of a time that an array is "undefined". They are either empty, or non-empty.
The snippet first checks if @ARGV is non-empty. An array evaluated in scalar context returns the number of elements it contains. Since boolean context is a special case of scalar context, @ARGV evaluates to 0 (false) if it is empty, and 1 or more (true) if has contents.
It's best not to write code like this. If you have any switch processing to do, just use Getopt::Long. Every time I try to short cut around using it, I wind up needing it later, anyway. Your snippet will not work properly if -v is the second option. Getopt::Long would be unaffected, and it has the advantage of being tested and documented code.
I know the making the distinction between undefined and empty may seem pedantic. But making sure that you really get these kinds of details will help you avoid some nasty, subtle bugs.
| [reply] |
|
|
$verbose will be false, and @ARGV remains untouched.
| [reply] |
Re: ARGV question
by FunkyMonk (Chancellor) on Aug 18, 2008 at 21:13 UTC
|
(@ARGV # if @ARGV has elements
&& # and
$ARGV[0] eq '-v' # The first element of @ARGV is '-v'
&& # and
shift); # remove the first element from @ARGV
In Perl, && is a shortcutting operator. That is, in A && B, perl will only evaluate B if A is true. The first && in your code is a traditional logical AND but the second makes sure that shift is only executed if the first && is true (ie when @ARGV isn't empty and it's first element is '-v').
The logical result is then asssigned to $verbose: true IFF $ARGV[0] eq "-v" and has the side-effect of shifting @ARGV if it was.
| [reply] [d/l] [select] |
Re: ARGV question
by toolic (Bishop) on Aug 18, 2008 at 21:34 UTC
|
I just can't figure out what's getting assigned to $verbose
Just run some experiments...
> cat 705063.pl
my $verbose = (@ARGV && $ARGV[0] eq '-v' && shift);
if (defined $verbose) {
print "verbose:$verbose:\n";
}
else {
print "verbose not defined\n";
}
>
> ./705063.pl
verbose:0:
> ./705063.pl -v
verbose:-v:
> ./705063.pl -v -b -n
verbose:-v:
> ./705063.pl -b
verbose::
If no arguments are passed to the script, verbose will be 0.
If any arguments are passed to the script, and the 1st is NOT '-v', then verbose seems to be a zero-length string, but not 'undef'. Perhaps a more knowledgable Monk can explain why.
If any arguments are passed to the script, and the 1st is '-v', then verbose is '-v'.
If this behavior is not what you want and you have control over the code, I suggest re-writing it to achieve what you want in a way that you understand. | [reply] [d/l] |
|
I got curious about that behavior of the zero length result, went looking and now humbly share my findings.
In chapter 3 of Programming Perl it is said that
The equal and not-equal operators return 1 for true and "" for false (3.12)
and
The && and || operators differ from C's in that, rather than returning 0 or 1, they return the last value evaluated. (3.14)
so, @ARGV is greater than 0 and passes, eq fails and returns '', and thus && returns the last value evaluated, which is ''.
| [reply] [d/l] [select] |
Re: ARGV question
by Skeeve (Parson) on Aug 18, 2008 at 21:12 UTC
|
| [reply] [d/l] [select] |
|
No, $verbose is 0 if @ARGV is empty (the number of elements in @ARGV) and "" if there is something different in @ARGV (the result of the comparision).
| [reply] |
Re: ARGV question
by p1ato (Initiate) on Aug 18, 2008 at 21:14 UTC
|
'shift' with no arguments, as is the case here, pops the first item off of '@_'. '@_' is an array of arguments given to the current subroutine so the value assigned to $verbose is dependent on the scope of the line you gave. | [reply] |
|
shift doesn't just operate on @_. Outside of a subroutine it operates on @ARGV.
| [reply] |
|
| [reply] |
Re: ARGV question
by steve (Deacon) on Aug 19, 2008 at 02:57 UTC
|
I agree with toolic.
Is there a specific reason that you need this code, or was the purpose of the question purely for understanding? | [reply] |