Re: Or Operator
by fruiture (Curate) on Jul 30, 2004 at 23:04 UTC
|
The magic term is "operator precedence", it determines the order of execution or your atomic expressions.
A = B or C;
# as "=" has higher precedence than "or" it binds it's
# arguments "tighter", so this is equivalent to
(A = B) or C;
# so your expression is a disjunction
# which executes the left operand
(A = B)
# being an assignment, which returns B in the end
# and if that's false, the disjunction (or)
# returns C, which is irrelevant, because that's in void
# context
# but you want
A = (B or C)
# because that's an assignment, an assignment
# evaluates the right operand first
(B or C)
# which itself is a disjunction again and works as described
# above, returning B if true, otherwise C
# and that is then assigned to A, which must be an lvalue
# that means in Perl
my $page = ( $cgi->param("page") or "login" );
# or by using the high-precedence-OR "||"
my $page = $cgi->param("page") || "login";
# because "||" has higher precedence than "="
see perlop
| [reply] [d/l] |
|
| [reply] |
|
If you think it will set $ftp to the result of the new method call, and if that was false set $longin error, it will.
| [reply] |
Re: Or Operator
by thor (Priest) on Jul 31, 2004 at 14:27 UTC
|
As was stated above, you're having problems with operator precedence. Consider the following two one-liners:
perl -le '$a = undef or 1; print $a'
perl -le '$a = undef || 1; print $a'
You may have to change the single-quotes to double-quotes to get the above examples to run from the command line, depending on what platform you're on
As perlop tells us, 'or' has lower precedence than '=', while '||' has higher precedence than '='. So the first one-liner is equivalent to:
perl -le '($a = undef) or "foo"; print $a'
whereas the second one is equivalent to:
perl -le '$a = (undef or "foo"); print $a'
thor
Feel the white light, the light within
Be your own disciple, fan the sparks of will
With all of us waiting, your kingdom will come
| [reply] [d/l] [select] |
Re: Or Operator
by VSarkiss (Monsignor) on Jul 31, 2004 at 16:46 UTC
|
The answers above address your question directly. If you ever need to figure this out on your own, the B::Deparse module, which comes standard with every Perl distribution, can be very helpful:
$ perl -MO=Deparse -e 'my $foo = bar() or baz()'
baz() unless my $foo = bar();
-e syntax OK
$ perl -MO=Deparse -e 'my $foo = bar() || baz()'
my $foo = bar() || baz();
-e syntax OK
You can see how the two are interpreted very differently.
| [reply] [d/l] |
Re: Or Operator
by rjahrman (Scribe) on Jul 30, 2004 at 22:53 UTC
|
(It's me again.)
BTW, I got it to work with:
$page = $cgi->param("page") or $page = "login";
But this:
my $page = $cgi->param("page") or $page = "login";
Fails. Why? Is there something I can change to make it work? | [reply] |
|
my $page = $cgi->param("page") or $page = "login";
fails because that second $page is really the global variable; the scope where "$page" refers to the my variable only starts on the following statement. use strict would have alerted you to this (unless you have an outer $page, which is not a good idea for keeping your code maintainable.)
| [reply] [d/l] |
Re: Or Operator
by Avitar (Acolyte) on Jul 30, 2004 at 23:15 UTC
|
my $page = $cgi->param("page") Or "login";
should prob be rewritten as a conditional statement for clairy...
my($page) = $cgi->param("page");
if($page eq ""){ $page = "login";}
Try it with a lowercase 'or'; Remember if it is worth writing, it is worth writing clear... if possible even difficult code should be understandable by even the most unexperianced. | [reply] [d/l] [select] |
|
I think this is the clearest and most concise way to express it:
my $page = $cgi->param("page") || "login";
You might say that inexperienced people won't understand it, but once they see it a few hundred times (because this is a very common way of doing it), they'll probably get it.
| [reply] [d/l] |
|
Then again, if there is a chance that $cgi->param("page") will be 0 - and you want to accept that, || will not work correctly. We'll get // (defined-or) in Perl 5.10, fortunately.
| [reply] [d/l] |
|
my $page = $cgi->param( "page" );
unless( defined $page and $page ne "" ){ $page = "login"; }
Of course that's pretty clusmy and contains lots of unnecessary punctuation. Let's use a statement modifier instead:
my $page = $cgi->param("page");
$page = "login" unless defined $page and $page ne "";
Makeshifts last the longest.
| [reply] [d/l] [select] |