Old C dog.

K

Kent Feiler

I'm a long-time C programmer starting on Perl. I always begin by
assuming things are C-ish and discover that sometimes they aren't.
Here's a statement I'm wondering about that seems to be all over the
place in Perl. Generically:

$a = b() or c();

Does the "or" check an internal Perl program field, or the final value
of $a, or the return from b()? I think I'd understand it if someone
would tell me whether z() is executed in the following statements:

$a = 0 or z();

Is that the same as:

if ( $a = 0 ) {
z();
}

....and how about the simple:

a() or z();

Or am I still missing the point?


Regards,

Regards,


Kent Feiler
www.KentFeiler.com
 
P

Paul Lalli

Kent said:
I'm a long-time C programmer starting on Perl. I always begin by
assuming things are C-ish and discover that sometimes they aren't.
Here's a statement I'm wondering about that seems to be all over the
place in Perl. Generically:

$a = b() or c();

Does the "or" check an internal Perl program field

I have no idea what that means.

the 'or' operator is identical to the '||' operator in every way but
one - it has a lower precedence. More to the point in this case, 'or'
has a lower precedence than '='. Therefore, if you were to
parenthesize (is that a word?) this statement, it would be:

($a = b()) or c();

Therefore, $a is assigned the return value of b(), regardless of
anything else. Then, the boolean truth of that assignment (which is
also the return value of b()) is determined. If that happens to be
false, then c() is evaluated. If $a=b() is true, short-circuit-logic
says that the 'or' is already true, and so c() is never executed.

, or the final value
of $a, or the return from b()? I think I'd understand it if someone
would tell me whether z() is executed in the following statements:

$a = 0 or z();

Yes it is, but possibly not for the reason you're thinking. Again, it
is evaluated only because the first part of the 'or' statement - $a=0 -
returned false.
Is that the same as:

if ( $a = 0 ) {
z();
}

No, it's the exact opposite of that. In the or statement, z() is
evaluated if $a=0 is false. In the if statement, z() is evaluated if
$a=0 is true (which is impossible).
...and how about the simple:

a() or z();

In this case, a() is evaluated. If a() returns true, the statement is
finished. If a() returns false, z() is evaluated.
Or am I still missing the point?

For more on all the logical operators (&&, ||, !, and, or, not, xor)
checkout the relevant documentation:
perldoc perlop
 
K

Klaus Eichner

Kent Feiler said:
I'm a long-time C programmer starting on Perl. I always begin by
assuming things are C-ish and discover that sometimes they aren't.
Here's a statement I'm wondering about that seems to be all over the
place in Perl. Generically:

$a = b() or c();

Does the "or" check an internal Perl program field, or the final value
of $a, or the return from b()?

the equivalent expression with brackets:
( $a = b() ) or c();
see "perldoc perlop" -> "Logical or and Exclusive Or"

it calls subroutine b() and assigns the value returned by b() to variable
$a. If that value is logically false, i.e. numerically 0, '0', the empty
string '' or undef, then, and only then, subroutine c() is called. Any value
which might be returned by c() will be ignored.
I think I'd understand it if someone
would tell me whether z() is executed in the following statements:

$a = 0 or z();

Is that the same as:

if ( $a = 0 ) {
z();
}

No, it's the same as:
if ( ! ( $a = 0 ) ) {
z();
}

or...
unless($a = 0) {
z();
}

or even ...
z() unless $a = 0;
...and how about the simple:

a() or z();

This simply calls subroutine a(). If the value returned by a() is logically
false, then subroutine z() is called. Another way of achieving the same
result would be:

if (!a()) { z() }

or

unless (a()) { z() }

or

z() unless a();
Or am I still missing the point?

I don't think so.
But I would recommend to read the standard perl-documentation, in particular
"perldoc perlop" and, if you have a background in C programming, read
"perldoc perltrap" --> "C/C++ Traps".
 
D

Damian James

I'm a long-time C programmer starting on Perl. I always begin by
assuming things are C-ish and discover that sometimes they aren't.
Here's a statement I'm wondering about that seems to be all over the
place in Perl. Generically:

$a = b() or c();

Here there is a precedence issue between "=" (the assignment operator)
and 'or'. In Perl, 'or' is a lower-precedence syntactic sugar version
of the boolean 'or' operator, '||'. In this case, is it equivalent to

( $a = b() ) || c();

What you seem to be asking about, though, is the side-effect of evaluating
boolean expressions (which, AIUI, is done in C too). The above first
evaluates the expression "$a = b()", which will be the result of the
assignment of the return value of b() to $a, which will be whatever b()
returned. If that value is not true, then c() is called and it's return
value will be discarded. Either way, $a gets assigned to whatever b()
returned. If you had written

$a = b() || c();

where '||' has higher precedence than the assignment operator, then first
b() is called, if it's return value is true, then $a is assigned to that,
and c() isn't called. However, if it's return value is false, then c() is
called and whatever it returns is assigned to $a.
Does the "or" check an internal Perl program field, or the final value
of $a, or the return from b()? I think I'd understand it if someone
would tell me whether z() is executed in the following statements:

$a = 0 or z();

In that statement, z() will never be executed. If you were to write that as

$a = ( 0 or z() );
or
$a = 0 || z();

Then z() will be called every time.
Is that the same as:

if ( $a = 0 ) {
z();
}

Well, the '=' is the assignment operator, you are probably thinking
of the numeric comparison operatot, '==', or even the string comparison
operator, 'eq'. And in this case is is about evaulation, so it is closer
to:

if ( 0 ) {
$a = 0;
}
else {
$a = z();
}
...and how about the simple:

a() or z();

Or am I still missing the point?

The boolean operators are often used for their side effects as much as for
their meaning in a boolean context. Perl will evaluate the left side of
an expression containing '||' or '&&' first, and might evaluate the right
side depending on the result.

The point to remember is that for '||' (or 'or' in the appropriate context),
if the left side is true then the right side is not evaluated; whereas with
'&&' (or 'and' in the appropriate context) if the left side is false the
right side is not evaluated. You may see this effect used widely in code
that looks like

function( @args ) or die "Error: $!\n";

Here, function() is expected to return a true value, and in the case where
it does not, the program exits with an error. It would do so even if you
were capturing the return value:

my $return = function( @args ) or die "Error: $!\n";

Here, the assignment operator has higher precedence than 'or', like the
first example above. However, if the return value of function() is false,
even though it is assigned successfully to $return, the assignment operator
always returns the value assigned even if it is a false value, and in this
case that means the left hand side evaulates as false, so the right hand side,
die() is evaluated.

I recommend reading the perlop man page thoroughly, that is the place that
this material is covered in depth. If you're impatient, jump to the section
headed: "C-style Logical And".

--Damian
 
I

Ilmari Karonen

Damian James said:
In that statement, z() will never be executed. If you were to write that as

$a = ( 0 or z() );
or
$a = 0 || z();

Then z() will be called every time.

Did you check that?

$ perl -le '$a = 0 or print "Oops!"'
Oops!

Remember, the value of scalar assignment is the value being assigned.
That's so that you can write "$a = $b = 123", but it also makes it
easy to both save and check a value in one statement. You've probably
seen this idiom used like this:

my $arg = shift or die "Missing argument!\n"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top