John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

keys :: works without a leading % sigil, but keys main:: does not. What's the difference?

Replies are listed 'Best First'.
(tye)Re: Why is (keys ::) legal syntax?
by tye (Sage) on Nov 12, 2002 at 21:24 UTC

    In op.c there is specific code to allow for keys( bareword ) to be treated as keys( %bareword ). If you turn on warnings you will get: Hash %bareword missing the % in argument 1 of keys() which is how I found the code:

    case OA_HVREF: if (kid->op_type == OP_CONST && (kid->op_private & OPpCONST_BARE)) {
    and this makes me think that this is for compatability to something prior to Perl4.

    Add to this the long-standing habit of print( hello ) being the same as print( "hello" ) (other than the optional errors and warnings).

    Add to that a patch that noted that Module->Method() can sometimes be interpretted as Module()->Method() (or was it only Method Module that had that problem?) and that added support for the syntax Module::->Method() (or was it Method Module::?). I suspect that this is what made print( hello:: ) the same as print( "hello" ).

    So these (may) explain why keys( main ) and keys( main:: ) are the same as keys( %main ).

    Also consider that %main:: didn't use to work. You used to have to do %{"main::"}. And print( :: ) is the same as print( "::" ). So it makes some quirky sense that keys( :: ) is the same as keys( %:: ) which is now the same as keys( %{"main::"} ).

            - tye (those who don't know history are doomed to invent it)
Re: Why is (keys ::) legal syntax?
by japhy (Canon) on Nov 12, 2002 at 21:49 UTC
    Building upon what tye said, I've known about this for a while:
    push me, harder; pop goes_the_weasel; shift yeyes; # etc.
    It's legacy support from before Perl 5. It's icky, but it's excellent for poetry mode.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: Why is (keys ::) legal syntax?
by Mr. Muskrat (Canon) on Nov 12, 2002 at 20:38 UTC

    (keys ::) is the same as (keys %::) is the same as (keys %main::).
    main:: is a scalar that contains the value main.

    Just don't ask me why! Once again, I'm stumped!

    I had hoped that Data::Dumper might shed some light on it but so far it hasn't.

Re: Why is (keys ::) legal syntax?
by pg (Canon) on Nov 12, 2002 at 20:42 UTC
    Try this:
    keys main::::;
      perl -MO=Deparse -e"print join qq(\n), keys main::::::"
      turns into %::. However, using %:: turns into %main:: internally.
      a little bit more explaination:
      in main::::, the first set of :: is the operator, when the second set of :: is a val.
Re: Why is (keys ::) legal syntax?
by Mr. Muskrat (Canon) on Nov 12, 2002 at 20:46 UTC

    You keep coming up with these cool questions so would you care to share what you are working on?

      Well, I'm just trying to look busy.

      Seriously, I came up with this one when checking out attributes::bootstrap after reading tye's reply. My one-liner printed main's contents instead! Blame the shell for thinking %attributes was an environment variable, so it saw :: alone. Since %'s are a constant problem on the command line, I thought "oh, I can even leave it off when the context must be a hash?" just like the @ in the push in old versions of Perl. Well, it's inconsistant.

      For the others, deep symbol table and ref stuff, I'm working on Exporter::VA and generally trying to understand everything.

      —John