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

perl -e '$_[0]={1,1,2,2};keys %$_[0]' # no perl -e '$_[0]={1,1,2,2};print ref $_[0]' # wtf HASH perl -e 'keys %$_'. # ok perl -e 'keys %$_[0]' # no perl -e 'keys %$;[0]' # ok perl -e 'keys %$#[0]' # ok perl -e 'keys %$^[0]' # ok perl -e 'keys %$&[0]' # ok perl -e 'keys %$=[0]' # ok perl -e 'keys %$|[0]' # ok perl -e 'keys %$,[0]' # ok perl -e 'keys %$<[0]' # ok perl -e 'keys %$>[0]' # ok perl -MDevel::Peek -e 'Dump(%$_[0])' SV = NULL(0x0) at 0x100a29eb8 REFCNT = 2147483641 FLAGS = (READONLY,PROTECT) perl -MDevel::Peek -e 'Dump(%$^[0])' SV = IV(0x12b025cf0) at 0x12b025d00 REFCNT = 1 FLAGS = (PADTMP,IOK,pIOK) IV = 5016431784 perl -MDevel::Peek -e 'Dump(%$&[0])' SV = IV(0x14a0136f0) at 0x14a013700 REFCNT = 1 FLAGS = (PADTMP,IOK,pIOK) IV = 0 perl -MDevel::Peek -e 'Dump(%$^[0])' SV = IV(0x1590136f0) at 0x159013700 REFCNT = 1 FLAGS = (PADTMP,IOK,pIOK) IV = 5779793576 perl -MDevel::Peek -e 'Dump(%{$^[0]})' Number found where operator expected (Missing operator before "0"?) at + -e line 1, near "$^[0" syntax error at -e line 1, near "$^[0" perl -MDevel::Peek -e 'Dump(%$=[0])' SV = IV(0x14f025cf0) at 0x14f025d00 REFCNT = 1 FLAGS = (PADTMP,IOK,pIOK) IV = 1 perl -MDevel::Peek -e 'Dump(%$|[0])' SV = IV(0x1258256f0) at 0x125825700 REFCNT = 1 FLAGS = (PADTMP,IOK,pIOK) IV = 4924155560 perl -MDevel::Peek -e 'Dump(%$<[0])' SV = PVNV(0x12a009810) at 0x104631ea0 REFCNT = 2147483644 FLAGS = (IOK,NOK,POK,IsCOW,READONLY,PROTECT,pIOK,pNOK,pPOK) IV = 1 NV = 1 PV = 0x10447e94f "1" [BOOL PL_Yes] CUR = 1 LEN = 0 perl -MDevel::Peek -e 'Dump(%$>[0])' SV = PVNV(0x1440097f0) at 0x100bdded0 REFCNT = 2147483647 FLAGS = (IOK,NOK,POK,IsCOW,READONLY,PROTECT,pIOK,pNOK,pPOK) IV = 0 NV = 0 PV = 0x100a2a951 "" [BOOL PL_No] CUR = 0 LEN = 0 perl -MDevel::Peek -e 'Dump(%$;[0])' syntax error at -e line 1, near "%$;" perl -MDevel::Peek -e 'Dump(%$#[0])' syntax error at -e line 1, at EOF

Replies are listed 'Best First'.
Re: keys on scalar warnings and lack thereof (precedence)
by LanX (Saint) on May 14, 2026 at 10:21 UTC
    perl -e '$_[0]={1,1,2,2};keys %$_[0]' # no perl -e '$_[0]={1,1,2,2};print ref $_[0]' # wtf HASH

    Precedence rules!

    $ perl -E'$_[0]={1,1,2,2};say keys %{$_[0]}' # ttf° 21 $

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

    °) s/what/this/

Re: keys on scalar warnings and lack thereof
by ikegami (Patriarch) on May 14, 2026 at 16:39 UTC

    See Mini-Tutorial: Dereferencing Syntax.

    The curlies in a circumfix dereference can only be omitted if they contain a simple scalar like $NAME (or $BLOCK), not something more complicated like $_[0].

    %$_[0] should be %{ $_[0] } (circumfix notation) or $_[0]->%* (postfix notation).

      I didn't include %{$_[0]} because it's obviously ok:
      perl -MDevel::Peek -e 'Dump(%{$_[0]})' SV = PVHV(0x157010280) at 0x15700ae40 REFCNT = 1 FLAGS = (SHAREKEYS) ARRAY = 0x0 KEYS = 0 FILL = 0 MAX = 7 But what is this: perl -MDevel::Peek -e 'Dump(%$_[0])' SV = NULL(0x0) at 0x100939eb8 REFCNT = 2147483641 FLAGS = (READONLY,PROTECT) and this: perl -MDevel::Peek -e 'Dump(%$^[0])' SV = IV(0x159825cf0) at 0x159825d00 REFCNT = 1 FLAGS = (PADTMP,IOK,pIOK) IV = 5796572328 perl -MDevel::Peek -e 'Dump(%{$^[0]})' Number found where operator expected (Missing operator before "0"?)
      And all the other weird looking results?

        What exactly do you expect from broken code?

        $ perl -E' $_[0] = {}; say keys %$_[0]' Experimental keys on scalar is now forbidden at -e line 1. Type of arg 1 to keys must be hash or array (not index/value array sli +ce) at -e line 1, at EOF Execution of -e aborted due to compilation errors.

        Please note the not index/value array slice , because that's what's fed into keys.

        Try keys %{$_}[0] and compare the error messages...

        Update

        Admittedly, I've never used this before: Index/Value-Array-Slices

        Update

        > And all the other weird looking results?

        In the other attempts with special variables parsing is "broken". Use B::Deparse to check by your self.

        Perl should theoretically see %$^[0] etc as %{$^}[0] but doesn't , and I'm neither surprised nor shocked.

        These variables are not meant to hold array or hash refs, and skipping punctuation while parsing seems like an acceptable bug and might avoid other worse problems.

        Feel free to file a bug report, I doubt this will get a high priority.

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