in reply to Re: Problem combining hashes
in thread Problem combining hashes

This duplicates common keys.

Interestingly, with the postdereference, we can use a hash slice in an assigment:

my %A = (a => 1, b => 2, D => 3); my %Z = (z => 9, y => 8, D => 7); (\ my %all_keys)->@{keys %A, keys %Z} = (); say for keys %all_keys;

The same construct using the "old" dereference doesn't work:

@{ \ my %all_keys }{keys %A, keys %Z} = (); say for keys %all_keys; # Global symbol "%all_keys" requires explicit + package name (did you forget to declare "my %all_keys"?)
because, alas, the my is scoped inside the dereference block.

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^3: Problem combining hashes
by Danny (Chaplain) on Mar 15, 2024 at 17:34 UTC
    (\ my %all_keys)->@{keys %A, keys %Z} = ();
    What is the "\ my" doing? It seems to work without the "\".
      'It seems to work without the "\".'

      That seemed odd to me so I checked it. I modified the output slightly for ease of comparison.

      With \:

      $ perl -Mstrict -Mwarnings -E ' my %A = (a => 1, b => 2, D => 3); my %Z = (z => 9, y => 8, D => 7); (\ my %all_keys)->@{keys %A, keys %Z} = (); say for "@{[sort keys %all_keys]}"; ' D a b y z

      Without \:

      $ perl -Mstrict -Mwarnings -E ' my %A = (a => 1, b => 2, D => 3); my %Z = (z => 9, y => 8, D => 7); (my %all_keys)->@{keys %A, keys %Z} = (); say for "@{[sort keys %all_keys]}"; ' D a b y z

      So I can confirm that behaviour. I then ran both of those through B::Deparse.

      With \:

      $ perl -Mstrict -Mwarnings -MO=Deparse -E ' my %A = (a => 1, b => 2, D => 3); my %Z = (z => 9, y => 8, D => 7); (\ my %all_keys)->@{keys %A, keys %Z} = (); say for "@{[sort keys %all_keys]}"; ' use warnings; use strict; use feature 'current_sub', 'bitwise', 'evalbytes', 'fc', 'isa', 'modul +e_true', 'postderef_qq', 'say', 'signatures', 'state', 'unicode_strin +gs', 'unicode_eval'; my(%A) = ('a', 1, 'b', 2, 'D', 3); my(%Z) = ('z', 9, 'y', 8, 'D', 7); @(\my %all_keys){keys %A, keys %Z} = (); say $_ foreach (join $", @{[sort(keys %all_keys)];}); -e syntax OK

      No huge surprises there.

      Without \:

      $ perl -Mstrict -Mwarnings -MO=Deparse -E ' my %A = (a => 1, b => 2, D => 3); my %Z = (z => 9, y => 8, D => 7); (my %all_keys)->@{keys %A, keys %Z} = (); say for "@{[sort keys %all_keys]}"; ' use warnings; use strict; use feature 'current_sub', 'bitwise', 'evalbytes', 'fc', 'isa', 'modul +e_true', 'postderef_qq', 'say', 'signatures', 'state', 'unicode_strin +gs', 'unicode_eval'; my(%A) = ('a', 1, 'b', 2, 'D', 3); my(%Z) = ('z', 9, 'y', 8, 'D', 7); @all_keys{keys %A, keys %Z} = (); say $_ foreach (join $", @{[sort(keys %all_keys)];}); -e syntax OK

      The lexical variable my %all_keys appears to have been changed in favour of the package variable %all_keys (no my). A search through perlref provided no answers; although, it's not impossible that I missed something. I don't have time to investigate further; perhaps another monk can shed some light on this.

      All of the above used:

      $ perl -v | head -2 | tail -1 This is perl 5, version 39, subversion 3 (v5.39.3) built for cygwin-th +read-multi

      I repeated everything with the earliest Perl version I have available:

      $ perl -v | head -2 | tail -1 This is perl 5, version 30, subversion 0 (v5.30.0) built for cygwin-th +read-multi

      The results were the same except the "use feature" list was slightly different: signatures out; switch in.

      use feature 'current_sub', 'bitwise', 'evalbytes', 'fc', 'postderef_qq +', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval';

      I don't believe that difference has any relevance to what's being tested.

      — Ken

        This works also.
        my %all_keys; %all_keys->@{keys %A, keys %Z} = ();
        deparser says
        my %all_keys; @all_keys{keys %A, keys %Z} = ();
        So it doesn't seem to be requiring a hash reference in that context.
Re^3: Problem combining hashes
by LanX (Saint) on Mar 15, 2024 at 14:07 UTC
    Yeah sorry I missed that requirement.

    The OP wasn't really a SSCCE tho. Duplicated keys would have shown the problem. :)

    Personally I would go for a clear 2 line approach, all this dereferencing doesn't make it more readable.

    Or to repeat my old mantra:

    • Perl would be better of with autobox-methods¹ {%A, %Z}->keys
    On a side note: I always have the feeling that a big deal of perl4's appeal got lost with my, because of conceptual problems.

    Hmm...People will misunderstand this.

    What I mean is that many things are elegantly solved if you don't need 'my'. A language design problem.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

    ¹) compare autobox

Re^3: Problem combining hashes
by jh (Beadle) on Mar 15, 2024 at 14:06 UTC
    (\ my %all_keys)->@{keys %A, keys %Z} = ();

    LOL, I cannot condone that foolery.