Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Perl Idioms Explained - my $count = () = /.../g

by japhy (Canon)
on Feb 04, 2006 at 19:14 UTC ( [id://527973]=perlmeditation: print w/replies, xml ) Need Help??

Perl Idioms Explained - my $count = () = /.../g
my $str = "here are some words"; my $count = () = $str =~ /\S+/g;
The "empty parentheses" idiom is one that is used to force list context on an expression, and yet return a scalar: the count of items in that list. We are often told that there is no way to get the size of a list -- it must either be iterated over, or stored in an array, or some other means -- because when you try treating a list as a scalar, you're no longer dealing with a list: you're enforcing scalar context on some expression. Here are some examples:
my $last_operand = ("a", "b", "c"); # "c" my $true_or_false = /\w+/g; # 1 or "" my $dunno = some_function(); # who knows?!
The last example is particularly nasty: the return value of the function will be evaluated in scalar context. If that value is @array, then you'll get the size of the array; if it's @array[0,1], you'll get $array[1].

So how does the empty parentheses idiom work? It uses a little-exercised rule: a list assignment in scalar context returns the number of elements on the right-hand side of the list assignment. That's probably also rarely-spoken, since it's a bit dense. What it means is that an expression like (LIST1) = (LIST2), in scalar context, returns the number of elements in LIST2 (not LIST1). This means (LIST1) could be replaced with () and the scalar value returned would still be the size of LIST2.

This trick is most frequently used in conjunction with a regex with the "global" switch on it. In scalar context, such a regex would only match once, but in list context, it matches exhaustively. To get all such matches, one would do @matches = /.../g. But if we aren't interested in keeping the matches around, and instead just want to know how many there are, we could replace @matches with (), and evaluate it all in scalar context: my $count = (() = /.../g);. Of course, those outer parentheses are unnecessary, so the idiom becomes my $count = () = /.../g;.

Summary

It forces an expression to be evaluated in list context, and returns the number of elements returned by that expression.


Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

Replies are listed 'Best First'.
Re: Perl Idioms Explained - my $count = () = /.../g
by fergal (Chaplain) on Feb 04, 2006 at 19:22 UTC
    =()= has been known on occasion as the "goatse" operator. While it's not actually an operator, it is the funniest name for a perl idiom I've ever heard (if you get the joke great, if not, research it at your own peril).
      =()= has been known on occasion as the "goatse" operator. While it's not actually an operator, it is the funniest name for a perl idiom

      It's unfortunate that a Perl "function" (or idiom) has become the butt of a joke ;-)

      That is so unfortunate, as one who knows the reference.

      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

      Lordy...that'll make one's asshole pucker.

      meh.
Re: Perl Idioms Explained - my $count = () = /.../g
by zshzn (Hermit) on Feb 06, 2006 at 00:33 UTC
    Something else worth noting is that in the event of counting the amount of single characters tr() can be used.
    my $str = "here are some words"; my $count = $str =~ tr/e/e/; print "We sure do have a lot of e characters: $count\n";
Re: Perl Idioms Explained - my $count = () = /.../g
by truedfx (Monk) on Feb 07, 2006 at 15:27 UTC
    Just to have it mentioned: another way to do it is given in perldoc -f scalar:
    #!perl -l my $str = "here are some words"; my $count = @{[ $str =~ /\S+/g ]}; print $count;
    Personally, I think this makes the meaning clearer, but I'm sure others may disagree.
      I'd say "but that builds up and then destroys an array referencce", but I don't know which takes more time, and then I'd say "benchmark it", but this would be a case of micro-optimizing. So I will agree with your intent: use whichever construct is clearer to you.

      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: Perl Idioms Explained - my $count = () = /.../g
by santonegro (Scribe) on Feb 05, 2006 at 20:31 UTC
    a list assignment in scalar context returns the number of elements on the right-hand side of the list assignment
    I don't agree with that. An array assignment does this. A list assignment returns the last element. To wit:
    @A = (1,3,5); $scalar_array = @A; $scalar_list = (1,3,5); $scalar_weird = (1..5); print "SA: ", $scalar_array, $/; print "SL: ", $scalar_list, $/; print "SW: ", $scalar_weird, $/; =for shell metaperl@pool-71-109-151-76:~/tmp$ perl a.pl SA: 3 SL: 5 SW: =cut
      You misunderstood me. A list assignment in scalar context returns the number of elements.
      my $count = (LIST1) = (LIST2);
      The chunk in bold is the list assignment. That is put in scalar context by the my $count = ... part.

      Please see Re: Longest repeated string... for further clarification.


      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
      About the
      $scalar_weird = (1..5); print "SW: ", $scalar_weird, $/; SW:
      -it's not a 'range' operator but a 'flip-flop', returns false in your case, http://perlhacks.com/2014/01/dots-perl/

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://527973]
Approved by gmax
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (7)
As of 2024-03-29 13:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found