有人想在use函数语句中使用数组变量代替数组(列表)文字,如:
my @list = qw(foo zoo);
use Module @list;
Run Code Online (Sandbox Code Playgroud)
代替
use Module qw(foo zoo);
Run Code Online (Sandbox Code Playgroud)
所以她写道:
my @consts = qw(PF_INET PF_INET6);
use Socket @consts;
printf "%d, %d\n", PF_INET, PF_INET6;
Run Code Online (Sandbox Code Playgroud)
看似按预期工作:
2,10
然后,她正在使用其他模块,例如Time::HiRes.代替
use Time::HiRes qw(CLOCK_REALTIME CLOCK_MONOTONIC);
printf "%d, %d\n", CLOCK_REALTIME, CLOCK_MONOTONIC;
Run Code Online (Sandbox Code Playgroud)
0,1
她这样做:
my @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
use Time::HiRes @consts;
printf "%d, %d\n", CLOCK_REALTIME, CLOCK_MONOTONIC;
Run Code Online (Sandbox Code Playgroud)
0,0
它突然不起作用,就像它与Socket模块一起工作!这里发生了一件坏事.
(......这是在非严格的环境中.如果她使用use strict,她甚至会出错.另一方面,她在她的第一个看似有效的例子中没有任何暗示 - 即使她在use strict; use warnings; use diagnostics那里.)
现在她想探索这种奇怪的行为.尝试导入空列表:
my @consts = ();
use Socket @consts;
printf "%d, %d\n", PF_INET, PF_INET6;
Run Code Online (Sandbox Code Playgroud)
2,10
令人惊讶地工作,虽然它可能不应该,如:
use Socket ();
printf "%d, %d\n", PF_INET, PF_INET6;
Run Code Online (Sandbox Code Playgroud)
0,0
然后她稍微深入了解这些模块并意识到,两个模块之间的区别在于这些常量分别是未@EXPORT编辑的.
她的结论是,这use Module @list并不像她期望的那样有效.
对此最好的解释是什么?她做错了什么 - 在use声明中使用预定义数组的正确方法是什么?
sim*_*que 19
这与代码执行时有关.use在编译时执行,而my @list只在运行时执行.因此,数组不存在加载模块的点.
该模块插座出口 PF_INET和PF_INET6在默认情况下,如果你把它放在不要紧use线.但是Time :: HiRes 默认情况下不会导出内容.
你得到的错误strict是:
使用"严格潜艇"时不允许使用Bareword"CLOCK_REALTIME"...
这告诉我们Perl不知道这CLOCK_REALTIME是一个sub,这是真的,因为当我们这样做时它没有被加载:
my @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
use Time::HiRes @consts;
printf "%d, %d\n", CLOCK_REALTIME, CLOCK_MONOTONIC;
Run Code Online (Sandbox Code Playgroud)
什么use确实是require模块和import自变量在编译时的列表.所以它是一样的:
BEGIN {
require foo;
foo->import();
}
Run Code Online (Sandbox Code Playgroud)
知道了,我们可以自己做:
use strict; use warnings;
BEGIN {
my @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
require Time::HiRes;
Time::HiRes->import(@consts);
}
printf "%d, %d\n", CLOCK_REALTIME, CLOCK_MONOTONIC;
__END__
0, 1
Run Code Online (Sandbox Code Playgroud)
像这样它可以工作,因为数组@const在同一范围内定义,并且在Perl解释器执行时已经可用.
由于范围界定,只需BEGIN在使用前添加一个块将无法正常工作.
BEGIN {
my @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
}
use Time::HiRes (@consts);
Run Code Online (Sandbox Code Playgroud)
您可以通过在BEGIN块外声明变量来解决问题.这样,它将在下一个BEGIN块的范围内可用,并且该值已经设置,因为BEGIN块在编译时以FIFO顺序执行.
my @consts;
BEGIN {
@consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
}
use Time::HiRes (@consts);
printf "%d, %d\n", CLOCK_REALTIME, CLOCK_MONOTONIC;
__END__
0, 1
Run Code Online (Sandbox Code Playgroud)
所以回顾一下:
use strict,你就不能轻易找到问题所在BEGIN在前面添加一个块use并将my声明放在BEGIN它之外,它就可以了require代替use和import你自己,你也可以传递一个数组| 归档时间: |
|
| 查看次数: |
578 次 |
| 最近记录: |