Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

A "strange" behaviour, at least to me :)

by Anonymous Monk
on Apr 13, 2013 at 16:58 UTC ( #1028537=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I don't understand why in the call #2 below the arguments of the call do not "arrive" in the subroutine, I guess due to the use of sort.
Thanks in advance for clarifying this to me.

use strict; use Data::Dumper; use warnings; my @orig_values = (1,3,2); # 1 my @values = arraynosort(Values=>\@orig_values); print join(",",@values),"\n"; # 2 @values = sort arraynosort(Values=>\@orig_values); print join(",",@values),"\n"; sub arraynosort { my %args = @_; print Dumper \%args; my @values = @{$args{Values}}; return @values; }

Comment on A "strange" behaviour, at least to me :)
Download Code
Re: A "strange" behaviour, at least to me :)
by NetWallah (Abbot) on Apr 13, 2013 at 17:28 UTC
    Perl is mis-parsing the line :
    # 2 @values = sort arraynosort(Values=>\@orig_values);
    as
    @values = (sort arraynosort 'Values', \@orig_values);
    and using the "arraynosort" as a Sort sub.

    Adding parens fixes it:

    @values = sort (arraynosort(Values=>\@orig_values));
    An alternative fix is to give "sort" an empty "block", because it wants one:
    @values = sort {},arraynosort(Values=>\@orig_values);

                 "I'm fairly sure if they took porn off the Internet, there'd only be one website left, and it'd be called 'Bring Back the Porn!'"
            -- Dr. Cox, Scrubs

      @values = sort {},arraynosort(Values=>\@orig_values);
      passes a hash ref to sort. You meant
      @values = sort { $a cmp $b } arraynosort(Values=>\@orig_values);

      By the way, the least invasive solution is:

      @values = sort +arraynosort(Values=>\@orig_values);
Re: A "strange" behaviour, at least to me :)
by Kenosis (Priest) on Apr 13, 2013 at 17:35 UTC

    It's evident that you're encountering a Perl parsing issue which can be addressed by changing:

    @values = sort arraynosort( Values => \@orig_values );

    to this

    @values = sort ( arraynosort( Values => \@orig_values ) );

    Using B::Deparse, we can see how Perl parses your original line using my:

    perl -MO=Deparse -p -e 'my @values = arraynosort( Values => \@orig_val +ues );'

    Partial output:

    my(@values) = arraynosort('Values', \@orig_values);

    Now with the sort:

    perl -MO=Deparse -p -e '@values = sort arraynosort( Values => \@orig_v +alues );'

    Partial output:

    @values = (sort arraynosort 'Values', \@orig_values);

    Note that Perl is not 'seeing' the clustering represented by parentheses, and this produces the issue your encountering. However, if you group using parentheses, Perl 'sees' it the way you likely expected it to work:

    perl -MO=Deparse -p -e '@values = sort ( arraynosort( Values => \@orig +_values ) );'

    Partial Output:

    @values = sort(arraynosort('Values', \@orig_values));

    Hope this helps!

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (12)
As of 2014-10-21 21:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (111 votes), past polls