B
Ben Morrow
Quoth Brian McCauley said:OK I'd like to address this without digging into at the internals of how
the Perl compiler is implemented and looking only at the observable
behaviour of Perl programs that would behave differently under the two
cases.
require AtExit;
sub foo {
my $msg = shift;
print "+$msg";
AtExit->new(sub{ print "-$msg"});
}
my $q = (foo(1),foo(2),foo(3),foo(4));
print "|";
The "two different comma operators" model predicts '+1-1+2-2+3-3+4|-4'.
The "last element of list" model predicts '+1+2+3+4-1-2-3|-4' or
'+1+2+3+4-3-2-1|-4'
No, it doesn't. A list-in-scalar-context evaluates all its elements but
the last in *void* context, meaning that they get destroyed straight
away (before the next entry in the list is evaluated). As I said, the
two models predict the same behaviour, since context is determined at
compile time, making the distinction irrelevant unless one finds one
model easier to understand than the other. I just find it a little odd
that the perl docs seem to have picked the model that is *not* the way
it is actually implemented: maybe most people (unlike me) find the
'separate operators' model easier?
On Perl 5.8.4 I get '+1-1+2-2+3-3+4|-4'.
Yes, as I'd expect.
Something that puzzles me slightly is that if the above is modified to
sub bar {
(foo(1), foo(2), foo(3), foo(4));
}
my $q = bar;
print '|';
then we *do* get (5.8.2) '+1+2+3+4-3-2-1|-4'... it seems that 'returning
a list from a sub called in scalar context' does something slightly
different from 'evaluating a list in scalar context'; specifically, the
non-terminal elements of the list get scalar rather than void context,
and are destroyed later.
Ben