Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

chop() and list assignments

by converter (Priest)
on Mar 06, 2001 at 07:05 UTC ( #62423=perlquestion: print w/replies, xml ) Need Help??

converter has asked for the wisdom of the Perl Monks concerning the following question:

Someone on DALnet #perl challenged the channel to come up with the shortest subroutine to return the last character of its argument(s). I thought about it for a few seconds, and replied with:

sub foo {chop(@_=@_)}

This works as expected when foo() is passed a single scalar argument, but when foo() is passed a list, rather than returning the last character of the last list element as one would expect after reading the documentation on chop()*, it returns the last character of the first element in the list.

@a = ('ab','cd','ef'); print chop @a; # f print foo(@a); # b # the list assignment has the same effect here: print chop(@a=@a); # b

Changing foo() to:

sub foo {chop(@_=reverse @_)}
makes foo() work as expected.

Is this a documented behavior? I am probably missing some simple concept involved in list assignments, but I'd like to know why the list assignment has this effect.

*from perlfunc: If you chop a list, each element is the chopped. Only the value of the last `chop' is returned.

edit: chipmunk on 2001-03-05

Replies are listed 'Best First'.
Re: ttchop()/tt and list assignments
by dvergin (Monsignor) on Mar 06, 2001 at 07:55 UTC
    Why not just:
    sub foo {chop @_}; my @a = ('ab', 'cd', 'ef'); print foo(@a), "\n";; my $b = 'abcdef'; print foo($b), "\n";
    Which prints as expected:
    f f

      I should have been more specific about how we arrived at the problem. I wanted the function to work if it was passed a literal (remember that the elements of @_ are aliases, and that an assignment to @_ "de-aliases" @_'s elements). sub foo {chop @_}; would trip a Modification of a read-only value attempted error if passed 'string' or 10 + 100.

      At any rate, this was just in fun, and I noticed this "problem" and wanted to find out why Perl was behaving this way.

        No one has addressed the problem. Here is debugger code:
        DB<8> x chop(@a = ('abc','def','ghi')) 0 'c' DB<9> @a = qw( abc def ghi ) DB<10> x chop(@a) 0 'i'
        This feels so very wrong. What is that list assignment doing to chop()? Is it, for some reason, returning the last element assigned? All of the elements in the array are modified. Yet there are different return values. This is ungood.

        This occurs in 5.6.0. And it happens in bleadperl. This is a bug. It feels so bad.

        japhy -- Perl and Regex Hacker

      What does that do to @a?
Re: chop() and list assignments
by chipmunk (Parson) on Mar 06, 2001 at 23:25 UTC
    Here's a similar approach that avoids the bug in chop LIST: sub foo {chop(@_=pop)} Note: chop($_=pop) would work as well, but it also changes the value of $_, which could affect the rest of the code.
Re: chop() and list assignments
by InfiniteSilence (Curate) on Mar 06, 2001 at 22:50 UTC
    Why not do this:
    perl -e "@m=('hal', 'bob', 'didi'); sub foo {substr(@_[-1],-1) }; prin +t &foo(@m); print qq(\n@m);"
    which does not change the values passed to foo at all?

    Celebrate Intellectual Diversity

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://62423]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2020-10-21 16:41 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (220 votes). Check out past polls.