Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^2: question about: my $a AND sort {$a <=> $b} keys %hash

by AnomalousMonk (Archbishop)
on Aug 06, 2015 at 13:58 UTC ( [id://1137684]=note: print w/replies, xml ) Need Help??


in reply to Re: question about: my $a AND sort {$a <=> $b} keys %hash
in thread question about: my $a AND sort {$a <=> $b} keys %hash

You unfortunately just stumbled into one of the genuine design-flaws of the Perl interpreter ...

The basic design flaw is lexicalizing (if that's even a word) the name of the  $a special variable so that the homonym package variable becomes invisible (and also running without strictures or warnings).

c:\@Work\Perl\monks>perl -w -le "my $a = 1; ;; @unsorted = (2, 1, 4, 3, 0); @sorted = sort { printf qq{$a<=>$b }; $a <=> $b } @unsorted; print qq{\n}; print qq{@sorted}; " 1<=>1 1<=>3 1<=>4 1<=>1 1<=>0 0 2 1 4 3

I don’t recall if using a separate sort-comparison sub, rather than an inline anonymous, will address the matter or not. Can someone else please answer that?

I'm not sure why you can't answer the question yourself, but yes, a properly constructed named comparison function will sidestep the problem (update: although it would be better to address the issue directly):

c:\@Work\Perl\monks>perl -w -le "my $a = 1; ;; sub compare ($$) { my ($a, $b) = @_; return $a <=> $b; } ;; @unsorted = (2, 1, 4, 3, 0); @sorted = sort compare @unsorted; print qq{@sorted}; " 0 1 2 3 4
Please see sort.

Update: Changed code examples to eliminate  keys %hash expressions of OPed code and use a plain array for unsorted elements.


Give a man a fish:  <%-(-(-(-<

Replies are listed 'Best First'.
Re^3: question about: my $a AND sort {$a <=> $b} keys %hash
by choroba (Cardinal) on Aug 06, 2015 at 16:21 UTC
    I think the OP meant the following, which works:
    #! /usr/bin/perl use warnings; use strict; use feature qw{ say }; sub numerically { $a <=> $b } # lexical $a not in scope my @arr = sort qw( 1 2 10 11 12 ); say "@arr"; my $a; @arr = sort numerically @arr; say "@arr";

    Output:

    1 10 11 12 2 1 2 10 11 12

    Update: Added feature say. Thanks the Anonymous one.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Ah, that's interesting, because when I tried something similar, I had  $a within the lexical scope of the comparison function definition, which of course did not work:

      c:\@Work\Perl\monks>perl -wMstrict -lE "use warnings; use strict; ;; my $a = 1; ;; sub numerically { $a <=> $b } ;; my @arr = sort qw( 1 2 10 21 11 12 ); say qq{@arr}; ;; @arr = sort numerically @arr; say qq{@arr}; " 1 10 11 12 2 21 1 2 11 21 10 12
      I guess the take-away advice is that there should be a heavy application of Don't Do That™ whenever one contemplates creating lexical versions of special, non-punctuation variables.


      Give a man a fish:  <%-(-(-(-<

      Sure, if you've set PERL5OPT=Mfeature=say.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (1)
As of 2024-04-25 05:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found