Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Newbie: query about array assignment

by darren_uk (Initiate)
on Sep 13, 2012 at 13:31 UTC ( #993489=perlquestion: print w/ replies, xml ) Need Help??
darren_uk has asked for the wisdom of the Perl Monks concerning the following question:

This is my first post. And as usual I'm cribbing from existing code and learning on the job rather than having the luxury of time to read the Camel book...

What is the different between
@stuff = "This","That","Other";
and
@stuff = ("This","That","Other");
?

print @stuff; gives me what I expect with the parenthesis, but I'm curious what's happening (how perl's interpreting) the first form without the parenthesis.

Comment on Newbie: query about array assignment
Re: Newbie: query about array assignment
by LanX (Canon) on Sep 13, 2012 at 13:40 UTC
    "=" has a higher precedence than ",", thats why you need the parens.

    DB<104> dp @stuff = "This","That","Other"; { ((@stuff = 'This'), 'That', 'Other'); } DB<105> dp @stuff = ("This","That","Other"); { (@stuff = ('This', 'That', 'Other')); }

    UPDATE: the following example shows that you (almost) never really need parens for lists, it's just precendence:

    DB<111> sub list { "This","That","Other" } DB<112> @stuff = list() => ("This", "That", "Other")

    Cheers Rolf

    PS: don't be confused "dp" is my personal debugger-macro for using B::Deparse (with -p option to show parens)

Re: Newbie: query about array assignment
by choroba (Abbot) on Sep 13, 2012 at 13:40 UTC
    You can use B::Deparse (if reading the docum-entation is not enough) to see what perl thinks your code means:
    perl -MO=Deparse -e '@stuff = "This","That","Other";' @stuff = 'This', '???', '???';
    The question marks mean the constants were optimized away since they were used in a void context (as warnings would have told you).
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Newbie: query about array assignment
by sundialsvc4 (Monsignor) on Sep 13, 2012 at 15:19 UTC

    A really great way to find these things out is with a “Perl one-liner,” such as the following:   (shown with its output)

    perl -e 'my @stuff="This","That","Other"; use Data::Dumper; print Dumper(\@stuff);' $VAR1 = [ 'This' ];

    ... versus ...

    perl -e 'my @stuff=("This","That","Other"); use Data::Dumper; print Dumper(\@stuff);' $VAR1 = [ 'This', 'That', 'Other' ];

    Okay then, what is the difference here?   To find that out, let’s go to perldoc perlop, then search for Comma Operator, where we read in part:   (emphasis mine...)

    Comma Operator:

    Binary "," is the comma operator.   In scalar context it evaluates its left argument, throws that value away, then evaluates its right argument and returns that value.   This is just like C’s comma operator.

    In list context, it’s just the list argument separator, and inserts both its arguments into the list.  These arguments are also evaluated from left to right.

    In the Perl language, “context” is everything.   And so are the constructs use strict; use warnings; which will warn you about a lot of things.   For example, if we add this to it, look what we get now:

    perl -e 'use strict; use warnings; my @stuff="This","That","Other"; use Data::Dumper; print Dumper(\@stuff);' Useless use of a constant in void context at -e line 1. Useless use of a constant in void context at -e line 1. $VAR1 = [ 'This' ];

    Whoa!   Perl is now warning us about something, but only because we asked it to.   It is now explaining why the result might not have been what you expected from a reading of the perldoc paragraph cited above.   Also note (not shown) that it makes no quibble at all in the second case when the parentheses are inserted.

    The lesson here is that you must use strict; use warnings;, all the time.   Perl is designed to “DWIM = Do What I Mean” with a minimum of fuss, but sometimes it does not properly know “what you mean.”

    Now, there is one very small but very important thing that I wish to point out to you:   the back-slash that is used in print Dumper(\@stuff);.   Because I know that @stuff is an array, I do not want Perl to “flatten” that array into multiple parameters; I want to pass one reference to the whole array, so that I properly see it as what it is.   Consider what happens if I (errnoneously) omit it:

    perl -e 'my @stuff=("This","That","Other"); use Data::Dumper; print Dumper(@stuff);' $VAR1 = 'This'; $VAR2 = 'That'; $VAR3 = 'Other';

    Here, Perl “flattened” the parameter-list to the Dumper call, so that it was equivalent to Dumper('This', 'That', 'Other') and so this is how Dumper responded.   But it no longer shows the structure of the array-variable, which is why it’s erroneous.

    Last but not least, if you omit the use Data::Dumper; call, or if you do not have that package installed on your system, you’ll get this:

    Undefined subroutine &main::Dumper called at -e line 1.

Re: Newbie: query about array assignment
by AnomalousMonk (Monsignor) on Sep 13, 2012 at 17:21 UTC
    @stuff = "This","That","Other";

    When I first saw this and other, similar code fragments in this thread, my first expectation was that the comma expression  "This","That","Other" would evaluate to the right-most list item, "Other". After all, that's the rule: Evaluate left side, throw away, return right side in left-associative fashion.

    After a bit of thought, I realized that the rule is to evaluate the leftmost expression, toss the result, evaluate and return the result of the rightmost expression, left-associative. Of course, the leftmost expression has a side effect: it creates and initializes the  @stuff array. The following helped me elucidate the process:

    >perl -wMstrict -MO=Deparse,-p -le "my @stuff = 'One', 'Two', 'Three'; print qq{(@stuff)}; ;; my @stoff = scalar('Eine', 'Zwei', 'Drei'); print qq{(@stoff)}; ;; my @sniff = scalar(my @snarf = '111', '222', '333'); print qq{sniff: (@sniff) snarf: (@snarf)}; ;; my @stiff = ('Uno', 'Dos', 'Tres'); print qq{(@stiff)}; " Useless use of a constant (Eine) in void context at -e line 1. Useless use of a constant (Zwei) in void context at -e line 1. Useless use of a constant (222) in void context at -e line 1. Useless use of a constant (Two) in void context at -e line 1. Useless use of a constant (Three) in void context at -e line 1. BEGIN { $^W = 1; } BEGIN { $/ = "\n"; $\ = "\n"; } use strict 'refs'; ((my(@stuff) = 'One'), '???', '???'); print("(@stuff)"); (my(@stoff) = scalar(('???', '???', 'Drei'))); print("(@stoff)"); (my(@sniff) = scalar(((my(@snarf) = '111'), '???', '333'))); print("sniff: (@sniff) snarf: (@snarf)"); (my(@stiff) = ('Uno', 'Dos', 'Tres')); print("(@stiff)"); -e syntax OK >perl -wMstrict -le "my @stuff = 'One', 'Two', 'Three'; print qq{(@stuff)}; ;; my @stoff = scalar('Eine', 'Zwei', 'Drei'); print qq{(@stoff)}; ;; my @sniff = scalar(my @snarf = '111', '222', '333'); print qq{sniff: (@sniff) snarf: (@snarf)}; ;; my @stiff = ('Uno', 'Dos', 'Tres'); print qq{(@stiff)}; " Useless use of a constant (Eine) in void context at -e line 1. Useless use of a constant (Zwei) in void context at -e line 1. Useless use of a constant (222) in void context at -e line 1. Useless use of a constant (Two) in void context at -e line 1. Useless use of a constant (Three) in void context at -e line 1. (One) (Drei) sniff: (333) snarf: (111) (Uno Dos Tres)
Re: Newbie: query about array assignment
by Anonymous Monk on Sep 14, 2012 at 01:49 UTC

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (11)
As of 2014-08-29 10:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (280 votes), past polls