Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 为什么是;钥匙::“钥匙”;不是语法错误吗?_Perl - Fatal编程技术网

Perl 为什么是;钥匙::“钥匙”;不是语法错误吗?

Perl 为什么是;钥匙::“钥匙”;不是语法错误吗?,perl,Perl,出于好奇,我尝试了下面的一行代码,但惊讶的是,它在没有%符号的情况下居然可以工作 $ perl -E 'say for keys ::' 它适用于5.8.8和5.16.3两个版本;尽管后一版本发出了以下警告: 哈希%::在-e第1行的keys()参数中缺少%in 这到底是怎么回事?%有什么特别之处:允许它运行并打印其密钥,即使没有sigil 请注意,不会使用%main::打印按键 $ perl -E 'say for keys main::' Hash main:: missing the

出于好奇,我尝试了下面的一行代码,但惊讶的是,它在没有
%
符号的情况下居然可以工作

$ perl -E 'say for keys ::'
它适用于5.8.8和5.16.3两个版本;尽管后一版本发出了以下警告:

哈希%::在-e第1行的keys()参数中缺少%in


这到底是怎么回事?
%有什么特别之处:
允许它运行并打印其密钥,即使没有sigil

请注意,不会使用
%main::
打印按键

$ perl -E 'say for keys main::'
Hash main:: missing the % in argument 1 of keys() at -e line 1.
使用:

说:

use feature 'current_sub', 'evalbytes', 'fc', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval';
say $_ foreach (keys %main::);
因此它将::视为%::在这些perl版本中,没有严格的

TL;博士
并不特别;在Perl 5.22.0之前,您可以省略
%
并将任何标识符传递给

然而:

  • keys main::
    相当于
    keys%{'main'}
    或只是
    keys%main
  • keys::
    相当于
    keys%{':'}
    或只是
    keys%:

    请注意
    %main:
    (但不是
    %main
    )是
    %:
    的别名

相关代码见toke.c(以下为第5.8.8节):

/*在当前包中查找具有此名称的子例程,
除非名称是“Foo::”,在这种情况下,Foo是一个bearword
(和一个包名)*/
如果(len>2&&
PL_-tokenbuf[len-2]==':'&&PL_-tokenbuf[len-1]==':')
{
if(ckWARN(WARN_BAREWORD)和&!gv_fetchpv(PL_tokenbuf,FALSE,SVt_PVHV))
Perl_warner(aTHX_uPackwarn)(警告词),
“裸字\%s\”指的是不存在的包“,
PL_tokenbuf);
len-=2;
PL_tokenbuf[len]='\0';
gv=零gv;
gvp=0;
}
否则{
len=0;
如果(!gv)
gv=gv_fetchpv(PL_tokenbuf,FALSE,SVt_PVCV);
}
/*如果我们以前看到过全局覆盖,请使用正确的名称*/
国际单项体育联合会(gvp){
sv=newsvvn(“核心::全局:”,14);
sv_catpv(sv,PL_tokenbuf);
}
否则{
/*如果len为0,则newSVpv执行strlen(),这是正确的。
如果len不是零,那么它就是真实长度,
这样就可以正确地创建标量*/
sv=新闻VPV(PL_tokenbuf,len);
}
len
是当前令牌的长度

  • 如果令牌是
    main::
    ,则将创建一个新标量,其PV(字符串组件)设置为
    main

  • 如果标记是
    ,则使用
    gv_fetchpv
    获取typeglob

gv\u fetchpv
存在于gv.c中,并具有处理的特殊逻辑

如果(*namend==':')
namend++;
namend++;
name=namend;
如果(!*名称)
返回gv?gv:(gv*)*hv_fetch(PL_defstash,“main::”,6,TRUE);
这将获取存储在下键
main::
(即typeglob
*main::
)中的typeglob

最后,
keys
希望它的参数是散列,但如果您向它传递一个标识符,它会将其视为散列的名称。参见op.c中的
Perl\u ck\u fun

案例OA\u HVREF:
如果(kid->op_type==op_CONST&&
(儿童->私人和裸体)
{
char*name=SvPVx(((SVOP*)kid)->op_sv,n_a);
OP*const newop=newHVREF(newGVOP)(OP_GV,0,
gv_fetchpv(名称、真实值、SVt_PVHV));
if(ckWARN2(WARN_已弃用,WARN_语法))
Perl_warner(aTHX_uuPackwarn2(WARN_已弃用,WARN_语法),
“哈希%%s缺少%s()的参数%%IVdf中的%%”,
名称,(IV)numargs,PL_op_desc[类型];
免费(儿童);
kid=newop;
孩子->兄弟姐妹=兄弟姐妹;
*tokid=儿童;
}
否则如果(kid->op_type!=op_RV2HV&&kid->op_type!=op_PADHV)
坏类型(numargs,“hash”,PL_op_desc[type],kid);
mod(kid,type);
打破
这也适用于除
以外的事物:

$ perl -e'%h = (foo => "bar"); print for keys h'
foo
(,不再允许省略
%
符号。)

您还可以通过B::简明看到这一点:

$ 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
$perl-MO=简明-e'keys main::'
散列%main在-e第1行的keys()的参数1中缺少%1。
6离开[1参考]vKP/REFC->(结束)
1输入->2
2下一状态(主1-e:1)v:{->3
5键[t2]vK/1->6
4 rv2hv[t1]lKRM/1->5
3 gv(*主)s->4
-e语法正常
$perl-MO=简明-e'keys::'
哈希%::在-e第1行的keys()的参数1中缺少%1。
6离开[1参考]vKP/REFC->(结束)
1输入->2
2下一状态(主1-e:1)v:{->3
5键[t2]vK/1->6
4 rv2hv[t1]lKRM/1->5
3 gv(*main::)s->4
-e语法正常

我忘了是哪个版本了,但是你过去可以引用没有符号的哈希或数组。现在就尝试查找。@HunterMcMillen:你应该扩展它并将其作为答案发布。答案很好,你已经回答了我所有的问题
$ 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