Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

whats wrong reverse %x = reverse %h?

by borisz (Canon)
on Sep 28, 2004 at 16:34 UTC ( [id://394658]=perlquestion: print w/replies, xml ) Need Help??

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

Hi, I typed:
perl -e '%h = ( q => 2, w => 2 ); print reverse %h = reverse %h'
and wonder why I get three values back 'w22' I expect 'q2' or 'w2' at perls option. More testing shows even more wired results. In the example below, I expect %x reversed in %h but it is not. There was not even a 'a' => 2 pair in the original %h.
perl -MData::Dumper -le '%h = (1 => 2, a=>"b", c => 2); %h = reverse ( + %x = reverse %h); print Dumper({x => \%x, h =>\%h});' __OUTPUT__ $VAR1 = { 'x' => { 'b' => 'a', '2' => 'c' }, 'h' => { 'a' => 2, 'c' => 2 } };
Perl 5.8.4 cofuses me even more
perl5.8.4 -MData::Dumper -le '%h = (1 => 2, a=>"b", c => 2); %h = reve +rse ( %x = reverse %h); print Dumper({x => \%x, h =>\%h});' __OUTPUT__ $VAR1 = { 'x' => { 'b' => 'a', '2' => 'c' }, 'h' => { '' => 2 } };
can you explain this behavior please?
UPDATE: I really expect to lose the dupes. My point is that I expect that %h is a reverse of %x. But it is not for me, tested on
Mac OSX and Linux. So I really wonder that you get different output.
Boris

Replies are listed 'Best First'.
Re: whats wrong reverse %x = reverse %h?
by blokhead (Monsignor) on Sep 28, 2004 at 16:52 UTC
    The problem is with using the expression (%x = reverse %h) in list context.

    Notice that when I try to use it to make an anonymous array:

    use Data::Dumper; my %h = (1 => 2, a => "b", c => 2); print Dumper [ my %x = reverse %h ];
    I get a Bizarre copy of ARRAY in anonlist (perl v5.8.3). Same if I try to do
    print Dumper { my %x = reverse %h };
    I have no idea what (my %x = reverse %h) evaluates to in list context, but whatever it is, Perl doesn't like it. The fact it doesn't die with the Bizarre copy error when using that expression as function arguments might be a bug...

    Anyway, back to your original question, if you split the two reverses into two statements like

    %h = reverse do { my %q = reverse %h; %q };
    you'll get what you expect.

    blokhead

Re: whats wrong reverse %x = reverse %h?
by waswas-fng (Curate) on Sep 28, 2004 at 16:48 UTC
    Deparsed output:
    perl -MO=Deparse -MData::Dumper -le '%h = (1 => 2, a=>"b", c => 2); %h + = reverse ( %x = reverse %h); print Dumper({x => \%x, h =>\%h});' BEGIN { $/ = "\n"; $\ = "\n"; } use Data::Dumper; (%h) = (1, 2, 'a', 'b', 'c', 2); (%h) = reverse((%x) = reverse(%h)); print Dumper({'x', \%x, 'h', \%h}); -e syntax OK
    as stated above your reverse/reverse of the hash is causing you to lose dup keys...


    -Waswas
      Dont get me wrong, I really expect to lose the dup keys, but my output lose much more then the dupes.
      Boris
Re: whats wrong reverse %x = reverse %h?
by Zaxo (Archbishop) on Sep 28, 2004 at 16:40 UTC

    When you reverse the list you get from a hash, keys and values are exchanged. Making a hash from the reversed list, if two values are the same, only one of the previous keys will survive as a value.

    Added - I get 'w2' running your first example, but get the same as you with the second. There may be some optimization with aliases going wrong. I don't see that the construction is supposed to be undefined.

    After Compline,
    Zaxo

      Thats what I expect, but none of the examples show this behavior. the expected results from the first is for %h
      { 2 => 1, b=> 'a' } or { 2 => 'c', b=> 'a' }
      but the result is
      { a => 2, b => 2}
      even more unexpeted results from perl 5.8.4 where I get
      { '' => '2' }
      Boris
Re: whats wrong reverse %x = reverse %h?
by melora (Scribe) on Sep 28, 2004 at 21:19 UTC
    I did a little playing with this, to try to learn something.
    %h = (1 => 2, a=>"b", c => 2); %h = reverse (%x = reverse %h); foreach my $n (keys %h) { print "$n $h{$n}\n"; }
    Yeah, I know. Anyway, here's what I get:
    2 1 2 a b
    As if a duplicate element were eliminated by making the key null. But if I do
    %h = (1 => 2, a=>"b", c => 2); %x = reverse %h; %h = reverse %x; foreach my $n (keys %h) { print "$n $h{$n}\n"; }
    I get
    1 2 a b
    which is what I'd expect. Now, here's yet another thing: if I create another duplicate, d => 2 (at the end of the list), I still get the same end result; that duplicate is eliminated. In fact, in the first bit of code, I still get three lines of output. If there are duplicates, it doesn't seem to be guaranteed which one is eliminated by the reverse. I just looked at reverse in my Camel book and it doesn't mention anything about duplicates, so I suspect the order can't be relied upon. Typical for a hash.
Re: whats wrong reverse %x = reverse %h?
by jZed (Prior) on Sep 28, 2004 at 16:44 UTC
    I get 'w2' (no second 2) using perl 5.8.3. on winXP.

      Same for me on perl, v5.8.4 built for i686-linux.

      "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Re: whats wrong reverse %x = reverse %h?
by Keystroke (Scribe) on Sep 29, 2004 at 14:55 UTC
    Maybe it has something to do with print being on the same line?
    Weird.
    % perl -e '%h = (q => 1, w => 2, x => 0, y => 2);\ print join ",", reverse %h = reverse %h;' w,2,x,0,,2,q,21 % perl -e '%h = (q => 1, w => 2, x => 0, y => 2);\ %h = reverse %h; print join ",", reverse %h;' w,2,x,0,q,21

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (8)
As of 2024-04-19 08:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found