[Melbourne-pm] Regexps - how does the lexical scope of capture buffers work? (Was: Regexp: What's the right way to do this?)

Michael G Schwern schwern at pobox.com
Thu Oct 18 15:51:59 PDT 2012

On 2012.10.18 11:08 AM, Andrew McNaughton wrote:
> Perl does what you expect, but when you look closely it's pretty clever,
> and I don't know that I've seen this documented:
> if ( (undef,undef) ) { }   # a list of undefs is false
> @arr = (undef,undef);
> if ( @arr ) {}                        # an array of undefs is true
> At one level it's quirky behaviour that a perl programmer of many years
> may not have considered.  At another level, it enables a very useful
> idiom, and we can mostly just get on and use it without worrying about
> the subtleties.  Very perlish.

It's worse than that.

    print "True" if (undef, 1);     True
    print "True" if (1, undef);	    False

Why?  Because that's not really a list, it's the scalar comma operator.  From

   Binary "," is the comma operator.  In scalar context it evaluates its
   left argument, throws that value away, then evaluates its right
   argument and returns that value.  This is just like C's comma operator.

   In list context, it's just the list argument separator, and inserts
   both its arguments into the list.  These arguments are also evaluated
   from left to right.

@arr = (undef, undef) is true in a condition because an array in scalar
context returns the number of elements.

(undef, undef) is false as a condition because its in scalar context so its
the comma operator.  Its scalar return value is the last expression, undef.

(undef, 1) is true as a condition for the same reason, but its last expression
is 1.

The problem is inflamed by pretending the scalar comma operator is a "list"
and involving it in the "list vs array" madness.

Given how often one intends to use the comma operator as the comma operator,
rather than mistakenly using it, the language would have been better off
without overloading the meaning of comma.

The comma operator is a bit silly, just syntax sugar for "cram a bunch of
statements into one line and return the last one" usually used for evil.  It
doesn't even apply any runtime logic.

    my $foo = (foo(), bar(), baz());

is equivalent to

    my $foo = baz();

124. Two drink limit does not mean first and last.
    -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army

More information about the Melbourne-pm mailing list