Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Doubley surprised by fat commas

by GrandFather (Saint)
on Jun 09, 2021 at 21:43 UTC ( #11133705=perlquestion: print w/replies, xml ) Need Help??

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"; }


'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

Replies are listed 'Best First'.
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

      Thanks for finding "perldata". There should have been references to it in "perlsyn" & "perlop".

    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 (Vicar) 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.

Re: Doubley surprised by fat commas (updated)
by AnomalousMonk (Bishop) 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 (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 (64).)

    Update: Note that fun( => 'foo') is also a syntax error.

    Give a man a fish:  <%-{-{-{-<

Re: Doubley surprised by fat commas (updated)
by LanX (Sage) on Jun 09, 2021 at 22:33 UTC
    here what B::Deparse sees, comments added
    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__


    ) yep already discussed here => gist: multiple "empty" commas are ignored

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re: Doubley surprised by fat commas
by jo37 (Hermit) on Jun 10, 2021 at 09:51 UTC

    This is very similar to the Winking fat comma.



      Except that => => (to which I assume you're referring) does not disable leftward stringification by => as ,=> does:

      Win8 Strawberry (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 (64).)

      Give a man a fish:  <%-{-{-{-<

        Of course a double "fat comma" does not act as the "Winking fat comma". There are four ways to combine two of "fat comma" and "comma". What they have in common is that there is never an additional undef inserted in the list.


Re: Doubley surprised by fat commas
by cavac (Curate) 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";'

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11133705]
Front-paged by davies
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (1)
As of 2021-10-18 07:42 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (73 votes). Check out past polls.