TL DR
::not special; Prior to Perl 5.22.0, you can omit %and pass any identifier keys.
:
keys main:: keys %{'main'} keys %mainkeys :: keys %{'::'} keys %::.
, %main:: ( %main) %::.
toke.c( 5.8.8):
if (len > 2 &&
PL_tokenbuf[len - 2] == ':' && PL_tokenbuf[len - 1] == ':')
{
if (ckWARN(WARN_BAREWORD) && ! gv_fetchpv(PL_tokenbuf, FALSE, SVt_PVHV))
Perl_warner(aTHX_ packWARN(WARN_BAREWORD),
"Bareword \"%s\" refers to nonexistent package",
PL_tokenbuf);
len -= 2;
PL_tokenbuf[len] = '\0';
gv = Nullgv;
gvp = 0;
}
else {
len = 0;
if (!gv)
gv = gv_fetchpv(PL_tokenbuf, FALSE, SVt_PVCV);
}
if (gvp) {
sv = newSVpvn("CORE::GLOBAL::",14);
sv_catpv(sv,PL_tokenbuf);
}
else {
sv = newSVpv(PL_tokenbuf,len);
}
len - .
main::, PV ( ), main.
::, glob gv_fetchpv.
gv_fetchpv gv.c :::
if (*namend == ':')
namend++;
namend++;
name = namend;
if (!*name)
return gv ? gv : (GV*)*hv_fetch(PL_defstash, "main::", 6, TRUE);
glob, , main:: (.. typeglob *main::).
, keys , , , . . Perl_ck_fun op.c:
case OA_HVREF:
if (kid->op_type == OP_CONST &&
(kid->op_private & OPpCONST_BARE))
{
char *name = SvPVx(((SVOP*)kid)->op_sv, n_a);
OP * const newop = newHVREF(newGVOP(OP_GV, 0,
gv_fetchpv(name, TRUE, SVt_PVHV) ));
if (ckWARN2(WARN_DEPRECATED, WARN_SYNTAX))
Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
"Hash %%%s missing the %% in argument %"IVdf" of %s()",
name, (IV)numargs, PL_op_desc[type]);
op_free(kid);
kid = newop;
kid->op_sibling = sibl;
*tokid = kid;
}
else if (kid->op_type != OP_RV2HV && kid->op_type != OP_PADHV)
bad_type(numargs, "hash", PL_op_desc[type], kid);
mod(kid, type);
break;
, :::
$ perl -e'%h = (foo => "bar"); print for keys h'
foo
( 5.22.0 %.)
B:: Concise:
$ perl -MO=Concise -e'keys main::'
Hash %main missing the % in argument 1 of keys() at -e line 1.
6 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
5 <1> keys[t2] vK/1 ->6
4 <1> rv2hv[t1] lKRM/1 ->5
3 <$> gv(*main) s ->4
-e syntax OK
$ perl -MO=Concise -e'keys ::'
Hash %:: missing the % in argument 1 of keys() at -e line 1.
6 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
5 <1> keys[t2] vK/1 ->6
4 <1> rv2hv[t1] lKRM/1 ->5
3 <$> gv(*main::) s ->4
-e syntax OK