GrandFather has asked for the wisdom of the Perl Monks concerning the following question:
In a recent post I noticed on_success => => sub { and thought, "huh, that's gotta hurt". To my surprise the extra => didn't have the effect I expected. I did a little experimenting:
use strict;
use warnings;
showParams(fat => => 'comma');
showParams('real', , 'comma');
showParams('explicit', undef, 'comma');
sub showParams {
my @params = @_;
for my $param (@params) {
if (!defined $param) {
print ">undef<\n";
next;
}
if (ref $param) {
print "'", ref $param, "'\n";
next;
}
print "'$param'\n";
}
printf "\n";
}
Prints:
'fat'
'comma'
'real'
'comma'
'explicit'
>undef<
'comma'
I expected to see the >undef< line for each version of the call to showParams. What am I missing?
perl -v reports: This is perl 5, version 32, subversion 1 (v5.32.1) built for MSWin32-x64-multi-thread.
Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
Re: Doubley surprised by fat commas
by GrandFather (Saint) on Jun 09, 2021 at 23:57 UTC
|
Being Perl there's lots of documentation. I spent some time trawling through said documentation without finding anything to suggest this was expected behavior for a function call list before posting my question. I intended to mention that in my OP, but a meeting intervened and I did a hasty finish and post.
I'm afraid "That's what Perl does" answers don't really advance the needle on the understanding gauge, so I did some more digging. The key is in perldata in the List value constructors section:
LISTs do automatic interpolation of sublists. ... The null list is represented by (). Interpolating it in a list has no effect. Thus ((),(),()) is equivalent to (). ... lists may end with an optional comma to mean that multiple commas within lists are legal syntax. The list 1,,3 is a concatenation of two lists, 1, and 3, the first of which ends with that optional comma. 1,,3 is (1,),(3) is 1,3
So, there we are. It is intended and documented behavior, and I've learned something. Turns out the information is in the data, not the operator.
Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
| [reply] |
|
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: Doubley surprised by fat commas
by parv (Parson) on Jun 09, 2021 at 21:57 UTC
|
You are missing that you are dealing with Perl. Recently when experimenting with sub signatures, I relearned that , , in a list flattens to as-if-there-was-no-second-comma while expecting an undef. Like you. (Note to self: empty list is also, effectively, removed in (2, (), 4 ) to give (2, 4).)
perlop mentions "Comma Operator" ("list argument separator" in list context), but does not touch the above.
| [reply] [d/l] [select] |
Re: Doubley surprised by fat commas (updated)
by AnomalousMonk (Archbishop) on Jun 09, 2021 at 22:05 UTC
|
Similar to parv's comment:
A function argument list is a list (and assigned to the magical
@_ array), and Perl flattens lists.
Win8 Strawberry 5.8.9.5 (32) Wed 06/09/2021 17:59:05
C:\@Work\Perl\monks
>perl -Mstrict -Mwarnings
use Data::Dump qw(dd);
sub fun { dd \@_; }
fun('foo');
fun('foo',,,,,,,,);
# fun(,,,,,,,,'foo'); # syntax error!
# fun(,'foo'); # syntax error!
fun('foo','bar');
fun('foo',,,,,,,'bar');
fun('foo' => => => => => => 'bar');
^Z
["foo"]
["foo"]
["foo", "bar"]
["foo", "bar"]
["foo", "bar"]
(Update: Same results under Strawberry 5.30.3.1 (64).)
Update: Note that fun( => 'foo') is also a syntax
error.
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
Re: Doubley surprised by fat commas (updated)
by LanX (Saint) on Jun 09, 2021 at 22:33 UTC
|
D:\tmp\pm>perl -MO=Deparse
print "a"=> =>"c";
print "d",,"e";
print ,"f";
print =>"d";
__END__
print 'a', 'c';
print 'd', 'e';
print($_), '???'; # comma seen as scalar comma separator
'???', '???'; # "print" seen as hash-key, void constants fold
+ed away
__DATA__
D:\tmp\pm>perl -MO=Deparse
print (, "b");
print (=> "g");
__END__
syntax error at - line 1, near "print (,"
syntax error at - line 2, near "print (=>"
- had compilation errors.
__DATA__
(I hope print as pseudo-method of file-handles was not too magic for this test.)
IIRC one is supposed to enter undef explicitly when wanted, like when ignoring elements in list assignments.
I think what's happening here is a form of flattening where leading commas at RHS are ignored.°
D:\tmp\pm>perl -MO=Deparse
print "a"=> => => "c";
__END__
print 'a', 'c';
__DATA__
update
°) yep already discussed here => gist: multiple "empty" commas are ignored
| [reply] [d/l] [select] |
Re: Doubley surprised by fat commas
by jo37 (Deacon) on Jun 10, 2021 at 09:51 UTC
|
| [reply] |
|
Win8 Strawberry 5.8.9.5 (32) Thu 06/10/2021 9:48:30
C:\@Work\Perl\monks
>perl -Mstrict -Mwarnings
use Data::Dump qw(dd);
use constant APPLE => 1;
my %heesh = (APPLE => => 'red');
dd \%heesh;
my %hash = (APPLE , => 'red');
dd \%hash;
^Z
{ APPLE => "red" }
{ 1 => "red" }
(Same results for Strawberry 5.30.3.1 (64).)
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
|
| [reply] [d/l] |
Re: Doubley surprised by fat commas
by cavac (Parson) on Jun 10, 2021 at 07:52 UTC
|
This is (presumably) the same feature that allows to end a list on a comma without creating unwanted "undef" elements.
my @foo = (
'hello',
'world',
);
This makes copy/paste and reordering lines so much easier.
perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
| [reply] [d/l] [select] |
|
|