Re: or or
by ahunter (Monk) on Jul 08, 2000 at 15:53 UTC
|
They differ in precedence, and are otherwise the same.
This means that if you write:
$a=$b || $c;
$a=$b or $c;
Perl evaluates this:
$a=($b || $c);
($a=$b) or $c;
This changes what gets assigned to $a, and can also change
the context of a statement (from perlop):
@info = stat($file) || die; # oops, scalar sense of stat!
@info = stat($file) or die; # better, now @info gets its due
This occurs because die is in scalar context, (so || is
great for obfuscation!). || is also appropriate where you
want to cause the rightmost value to get assigned. That is:
$a=$b || $c
Would assign $c to $a if $b was false, otherwise it would
assign $b to $a. Whereas:
$a=$b or $c
Would not assign $c to $a when $b was false! In scalar
context, using || for dieing is fine, but you'll run
into trouble with things where context is important. or
is almost always what you mean in these cases.
If you still don't believe me, try this:
$a=0 or 1;
$b=0 || 1;
$a will be 0, and $b will be 1.
Andrew.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
>or is almost always what you mean in these cases.
|
This is largely a matter of programming style, and the nature of the project, not something inherent to Perl. I find myself using || about ten times as often as or.
Because most of my program data is non-zero, I find myself using a lot of things like:
$param = $value || $default;
OTOH, maybe I am using too many if/else blocks...
Paris Sinclair | 4a75737420416e6f74686572
pariss@efn.org | 205065726c204861636b6572
I wear my Geek Code on my finger.
| [reply] [Watch: Dir/Any] [d/l] |
|
I'm not sure what you mean here - you provide a classic
example of where or is most certainly not appropriate (as if you
use it, $param will never get the value of $default).
That is,
$param = $value or $default;
Will result in $param always getting the value of $value, never
$default. or has lower precedence than = (in fact
it has the absolute lowest precedence of all the operators).
Maybe it was just me not being clear, though. You should
always use 'or' where what you really want to say is:
($param=$value) or die "darn"
That is, you don't want the value of die to get assigned
to $param (yeah, die doesn't return very often. But it
forces scalar context, which is why the alternative is a Bad Thing).
Using or, your example would have to be:
$param=$value or $param=$default
So it's not always a matter of style.
Andrew. | [reply] [Watch: Dir/Any] [d/l] [select] |
|
RE: or or
by reptile (Monk) on Jul 08, 2000 at 15:48 UTC
|
Well, here's what the perlop manpage says:
As more readable alternatives to && and || when used for control flow, Perl provides and and or operators (see below). The short-circuit behavior is identical. The precedence of ``and'' and ``or'' is much lower, however, so that you can safely use them after a list operator without the need for parentheses:
unlink "alpha", "beta", "gamma"
or gripe(), next LINE;
With the C-style operators that would have been written like this:
unlink("alpha", "beta", "gamma")
|| (gripe(), next LINE);
So in other words, if you said this:
unlink "alpha", "beta", "gamma" || gripe();
the third argument to unlink would be "gamma" || gripe(); that is, always "gamma" and gripe() would never be evaluated.
'or' is smarter than that. Look at C-style Logical Or and Logical or and Exclusive or on the perlop manpage. It talks a bit about why this happens.
local $_ = "0A72656B636148206C72655020726568746F6E41207473754A";
while(s/..$//) { print chr(hex($&)) }
| [reply] [Watch: Dir/Any] [d/l] [select] |
Grouping Symbols?
by Kozz (Friar) on Jul 08, 2000 at 18:52 UTC
|
Or that's what we call them in mathematics. If you use parentheses around the arguments of a function, I think this would remove any concern over "or" vs. "||".
Like this:
open(FH, "filename.txt") || die "$!";
# OR
open(FH, "filename.txt") or die "$!";
Functionality should be identical in the two cases above, no?
Of course, this is only for calling of functions or something like that. It doesn't work the same with other above-mentioned examples such as
$a = $b || $c;
Which is an entirely different sort of thing. | [reply] [Watch: Dir/Any] [d/l] [select] |
|
You are right, the functionality is identical in the cases
you cite. But || comes with a *lot* of caveats when you
use it in circumstances like this. The RHS of or
will always be executed last (unless parentheses
are used, or there is more than one or). This means
if you want to say (psuedo-code):
if (open fails) { die }
or gives you a way of writing literally that. || means
something a bit different, and can cause considerable
confusion. It's a bad habit and a maintainance problem
to use the wrong operator for the job. See perlop.
Andrew. | [reply] [Watch: Dir/Any] [d/l] |
|
$foo = open(FH, "filename.txt") || die $!;
# not the same as
$foo = open(FH, "filename.txt") or die $!;
but they appear to be the same anyway ;) It's not the parentheses that's doing it, it's just the way it works. It's checking to see if the return of open() is true, and if not, tries to assign the return value of die to $foo, which never happens because it dies.
So it works the same either way, but it's actually doing two different things.
local $_ = "0A72656B636148206C72655020726568746F6E41207473754A";
while(s/..$//) { print chr(hex($&)) }
| [reply] [Watch: Dir/Any] [d/l] [select] |
RE: or or (or generally better for die)
by ybiC (Prior) on Jul 08, 2000 at 16:34 UTC
|
From reptile and ahunter's answers, it appears that using or instead of || for or die"message$!" would make an excellent habit, although not critical in every case.
Update: the rest of this thread makes my brain hurt :-P
| [reply] [Watch: Dir/Any] [d/l] [select] |
RE: or or (should be: or or ||)
by ybiC (Prior) on Jul 08, 2000 at 15:28 UTC
|
Oops - forgot to escape the || in the post's title. | [reply] [Watch: Dir/Any] |