in reply to Syntax Perl Version support $c = () = $a =~ /\./g

my $c = () = $a =~ /\./g;

This statement evaluates a regex in list context (imposed by the empty parens):
    () = $a =~ /\./g
and then evaluates the contents of the intermediate list captured by the parens in scalar context (imposed by the scalar assignment):
    my $c = ()
which evaluates to the number of elements in the list.

Some variants of this syntax (in which the regex matches are captured instead of being thrown away):

c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "print 'perl version: ', $]; ;; my $s = '3.5.9'; ;; my @ra; my $c = @ra = $s =~ m{ \d }xmsg; dd $c, \@ra; ;; $s = '8.6.5.1'; ;; $c = my @rb = $s =~ m{ \d }xmsg; dd $c, \@rb; " perl version: 5.008009 (3, [3, 5, 9]) (4, [8, 6, 5, 1])

... when did Perl begin supporting this type of structure?

AFAIK, Perl 5.x has always supported this, and I believe 4.x did as well, but I'm too lazy to do the research. (Update: See this for pertinent info on Perl 5 support for the  =()= "operator," and this for Perl 4 support (none).) This is a well-known and safe Perl idiom. In general, look for discussions of "context" and "context dependence."

Update: See also Context tutorial in the Tutorials section of the Monastery.


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

Replies are listed 'Best First'.
Re^2: Syntax Perl Version support $c = () = $a =~ /\./g
by haukex (Archbishop) on Jul 17, 2018 at 19:13 UTC
    AFAIK, Perl 5.x has always supported this

    I'm having some trouble running a bisect at the moment, but as a tentative result, it appears that Perl versions roughly before 5.004 didn't like the test program -e '$a="f.o.o.bar"; $b=()=$a=~/\./g; $b==3 or die $b' because Can't modify stub in list assignment at -e line 1, near "/\./g;". AFAICT it was not possible to assign to an empty list back then (a workaround seems to be $b = @{[]} = $a =~ /\./g;, which works on 5.000).

      haukex, thanks for digging in to find the lower limit, that was a key thing I needed to know. I'll note this in the docs, but I doubt I will ever need to go older than Perl 5.008 but I have learned painfully to never say never in this area.
Re^2: Syntax Perl Version support $c = () = $a =~ /\./g
by shmem (Chancellor) on Jul 17, 2018 at 22:47 UTC
    and I believe 4.x did as well

    No, it didn't and doesn't yet without patches ;-)

    perl 4 patchlevel 36:

    qwurx [shmem] ~> perl4 -e '$s="3.4.5";$r=()=$s=~/\./g;print$r,"\n"' Illegal item (LEXPR) as lvalue in file /tmp/perl-eEdymqE at line 1, ne +xt 2 tokens "/\./g;" Execution of /tmp/perl-eEdymqE aborted due to compilation errors.

    However, chaining assignments and evaluating ARRAY in scalar context did:

    qwurx [shmem] ~> perl4 -e '$s="3.4.5";$r=@r=$s=~/\./g;print$r,"\n"' 2

    Applying semantics of ARRAY to LEXPR (list expression) happened in perl5.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: thanks all
by h2 (Beadle) on Jul 17, 2018 at 19:14 UTC
    Thank you very much, I'm glad to see I can start digging into these more arcane operator collections. Thanks for the links as well, now I at least know what to be looking for. Your responses are exactly what I needed to know.