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

New user, confusion over print and lists

by jktstance (Novice)
on Jan 23, 2014 at 15:56 UTC ( #1071774=perlquestion: print w/ replies, xml ) Need Help??
jktstance has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I'm learning Perl (my only other programming experience is Tcl) and I'm having some trouble. I'm confused over lists, so I looked up some help and found this thread at Stack Overflow. I looked up the perldoc of reverse (reverse) and I on the page, there is some code, which I've slightly modified:
#!/usr/bin/perl use strict; use warnings; print join(", ", reverse "world", "One"), "\n"; # One, world print scalar reverse ("dlrow ,", "owT"),"\n"; # Two, world $_ = "dlrow ,eerhT"; print reverse; # No output, list context $_ = "dlrow ,ruoF"; print scalar reverse; # Four, world
I get the following output:
One, world Two, world Four, world
My first question is why isn't the third line printed? Reverse supposedly returns a list and the perldoc of print says that a list is one of it's arguments. Why doesn't this work? My second question is that if I explicitly state the $_ after reverse in the third print statement, then it prints out the string, but it is NOT reversed:
#!/usr/bin/perl use strict; use warnings; print join(", ", reverse "world", "One"), "\n"; # One, world print scalar reverse ("dlrow ,", "owT"),"\n"; # Two, world $_ = "dlrow ,eerhT"; print reverse $_; # No output, list context $_ = "dlrow ,ruoF"; print scalar reverse $_; # Four, world
I get the following output:
One, world Two, world dlrow, eerhTFour, world
What is going on here? Why does listing $_ explicitly as an argument to reverse cause print to work, but reverse() is not performed?

Comment on New user, confusion over print and lists
Select or Download Code
Re: New user, confusion over print and lists
by choroba (Abbot) on Jan 23, 2014 at 16:01 UTC
    When you specify $_ as an argument for reverse in list context, it is taken as the single member of the list to reverse. Equivalently, no arguments represent an empty list.
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      OK, I understand why the string is being printed back as is (1-length list). I'm still confused on why the behavior is different when I explicitly state $_ and when I do not.

      When reverse has no arguments, doesn't it just take $_? Is writing reverse; the same as reverse $_;? I'm imagining this to be the behavior, because print; and print $_; seem identical when I test them.

      EDIT: From the doc, I seems that reverse will ONLY work on $_ if it is in scalar context, which print is not. So I give it no arguments in list context, does reverse ignore $_, which the doc seems to imply it does. If so, is it just returning an empty list which is then passed to print?

Re: New user, confusion over print and lists
by LanX (Canon) on Jan 23, 2014 at 16:43 UTC
    This comment is wrong
    $_ = "dlrow ,eerhT"; print reverse $_; # No output, list context

    you get the one-element list ($_) reversed, which is the same list. Harder to spot since you forgot the newline this time.

    reverse does exactly like documented and explained by choroba

    • In list context, returns a list value consisting of the elements of LIST in the opposite order.

    • In scalar context, concatenates the elements of LIST and returns a string value with all characters in the opposite order.

    I think you are misunderstanding how context works, it's the LHS which decides how the RHS of reverse is interpreted and print always induces list context.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: New user, confusion over print and lists
by tobyink (Abbot) on Jan 23, 2014 at 17:07 UTC

    From the documentation for reverse:

    Used without arguments in scalar context, reverse() reverses $_.

    That is, $_ is only "special" to reverse when:

    • reverse is called with no arguments; and
    • reverse is called in scalar context.

    In the case of print reverse;, it is not in scalar context, so $_ is not special. You're calling reverse with the empty list as an argument. It reverses that list and return the result (which is still the empty list).

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2014-08-02 05:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Who would be the most fun to work for?















    Results (54 votes), past polls