2

From perldoc, in perldata, there is a line of code like:

$count = () = $string =~ /\d+/g;

It says $count will be set to the number of matches because assigning to the bracket means assigning to the empty list and it converts to list context. But when I do:

print (() = $string =~ /\d+/g);

I was expecting to print an array of matches but it prints nothing. If the empty list is nothing, how does the previous assignment from () to $count works? What does the first one mean by assigning to empty list and what does it actually do?


More specifically,

print $string =~ /\d+/g;                     #print all matches
print (() = $string =~ /\d+/g);              #print nothing (why)
print ($count = () = $string =~ /\d+/g);     #print number of matches (why again)

2 Answers 2

7

The key difference (perldoc perldata):

List assignment in scalar context returns the number of elements produced by the expression on the right side of the assignment:

$x = (($foo,$bar) = (3,2,1)); # set $x to 3, not 2

With $count = () = $string =~ /\d+/g;, you impose the scalar context on the list assignment, therefore the number of matches - elements produced by $string =~ /\d+/g - will be stored in $count variable.

But with print(() = $string =~ /\d+/g);, it's different:

Because print takes a LIST, anything in the LIST is evaluated in list context

And in list context, the list assignment result is the left side of assignment - which is, as you probably guessed, an empty list in this case. Printed, it just gives you an empty string.

I hope this example will be helpful to show the difference the context makes here.

my ($a, $b);
my $x = ($a, $b) = (1,2,3,4);
say $x;                        # 4  
my @x = ($a, $b) = (1,2,3,4);  
say join '-', @x;              # 1-2
Sign up to request clarification or add additional context in comments.

3 Comments

well im not asking the first line. im asking the second line why it prints nothing
@texasbruce: Until you understand its basic concepts (e.g. context), it might seem so.
I never see a language that returns right hand side of an assignment.
2

In

$count = () = $string =~ /\d+/g;

that () will put $string =~ /\d+/g in list context, so it will return a list of matched numbers, therefore the above statement equals something like

$count = (() = (num1, num2, ...))

the second assignment is a list assignment, and that $count = will put it in scalar context, and a list assignment in scalar context will return how many element there are in the right side of =.

The parameters of print is a list, and every of its elements will be evaluated in list context. Therefore in

print (() = $string =~ /\d+/g);

it equals you assigned $string =~ /\d+/g to () first, and use that result list (it is a empty list) as the arguments of print, which means that print statement equals

print ();

This could be fixed easily:

print scalar(() = $str =~ m/\d+/g), "\n";

scalar will put its argument to scalar context.

Another example, in

(() = @list, "\n")

the first element of this list, which is () = @list, will be evaluated in list context, and will result an empty list. So the above list equals

((), "\n")

Because sublists will be automatically interpolated in list, so the final result of the above list is simply

("\n")

6 Comments

But why print (() = $string =~ /\d+/g); does not print anything?
@texasbruce That print will try to output the empty list.
so u mean (()=(list)) returns empty list in list context but return number of list elements in scalar context? why the scalar context does not return 0 as empty list?
@texasbruce In (()=@list), the outer () means this is a list constructor, which will put every element of it in a list context. So the first element, which is list assignment () = @list, is evaluated in list context, not in scalar context, and will return an empty list.
Nipick: There is no such thing as a “list constructor”. In Perl, lists are not data structures (unlike arrays), they just describe a transient bunch of values on the stack. They have a role in Perl's semantics, but aren't actual “things” you can use. Nitpicking my nitpick: The perl VM actually has a “list” opcode which performs bookkeeping to prevent stack corruption. However, this opcode has no corresponding syntax, and parens only ever sort out precedence.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.