有人想在use函数语句中使用数组变量来代替数组(列表)文字,如下所示:
my @list = qw(foo zoo);
use Module @list;而不是
use Module qw(foo zoo);因此,她写道:
my @consts = qw(PF_INET PF_INET6);
use Socket @consts;
printf "%d, %d\n", PF_INET, PF_INET6;它似乎像预期的那样起作用:
2、10
然后,她正在使用其他模块,例如Time::HiRes。而不是
use Time::HiRes qw(CLOCK_REALTIME CLOCK_MONOTONIC);
printf "%d, %d\n", CLOCK_REALTIME, CLOCK_MONOTONIC;0,1
她这样做了:
my @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
use Time::HiRes @consts;
printf "%d, %d\n", CLOCK_REALTIME, CLOCK_MONOTONIC;0,0
它突然不能工作,就像它与Socket模块一起工作一样!这里发生了一些不好的事情。
(..在非严格的环境中。如果她使用use strict,她甚至会得到一个错误。另一方面,她在她的第一个看似有效的例子中完全没有得到任何提示--即使她在那里有use strict; use warnings; use diagnostics。
现在她想探索这种奇怪的行为。尝试导入空列表:
my @consts = ();
use Socket @consts;
printf "%d, %d\n", PF_INET, PF_INET6;2、10
令人惊讶的是,它也起作用,而它可能不应该,比如:
use Socket ();
printf "%d, %d\n", PF_INET, PF_INET6;0,0
然后,她稍微深入这些模块,并意识到,这两个模块之间的区别是,这些常量分别是/不是@EXPORT编辑的。
她的结论是use Module @list不像她期望的那样起作用。
对此最好的解释是什么?她做错了什么?在use语句中使用预定义数组的正确方法是什么?
发布于 2013-12-05 10:31:16
这与执行代码的时间有关。use在编译时执行,而my @list只在运行时执行。因此,数组不存在加载模块的点。
默认情况下,模块插座出口 PF_INET和PF_INET6,所以如果将它放在use行中并不重要。但是时间::默认情况下雇用不出口东西。
您在strict中遇到的错误是:
在使用“严格的潜艇”时不允许使用"CLOCK_REALTIME“一词。
这告诉我们Perl不知道CLOCK_REALTIME是一个子程序,这是正确的,因为我们这样做时没有加载它:
my @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
use Time::HiRes @consts;
printf "%d, %d\n", CLOCK_REALTIME, CLOCK_MONOTONIC;有吗?是require模块,import是编译时的参数列表。所以这和:
BEGIN {
require foo;
foo->import();
}知道了这一点,我们自己就能做到:
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就像这样,它将工作,因为数组@const是在相同的作用域中定义的,并且在Perl解释器执行它时已经可用。
由于作用域的限制,在使用前添加一个BEGIN块将使而不是工作。
BEGIN {
my @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
}
use Time::HiRes (@consts);您可以通过在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因此,概括地说:
use strict,你很难找到问题。BEGIN前面添加了一个use块,并将my声明放置在BEGIN之外,那么它可以工作。require而不是use和import,您也可以传递一个数组https://stackoverflow.com/questions/20396722
复制相似问题