Perl:使用Module @list

前端之家收集整理的这篇文章主要介绍了Perl:使用Module @list前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有人在使用函数语句中有一个想法使用数组变量代替数组(列表)文字,如:
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

然后,她正在使用其他模块,例如时间::高分辨率.代替

use Time::HiRes qw(CLOCK_REALTIME CLOCK_MONOTONIC);
printf "%d,CLOCK_REALTIME,CLOCK_MONOTONIC;

0,1

她这样做:

my @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
use Time::HiRes @consts;
printf "%d,0

它突然不起作用,就像它与Socket模块一起工作!
这里发生了一件坏事.

(..它是在非严格的环境中.如果她使用严格,她甚至会出错.另一方面,她在她的第一个看似有效的例子中没有任何暗示 – 即使她严格使用;使用警告;在那里使用诊断.)

现在她想探索这种奇怪的行为.尝试导入空列表:

my @consts = ();
use Socket @consts;
printf "%d,PF_INET6;

2,10

令人惊讶地工作,虽然它可能不应该,如:

use Socket ();
printf "%d,PF_INET6;

0,0

然后她稍微深入了解这些模块,并意识到两个模块之间的区别在于这些常量分别是@EXPORTed.

她的结论是使用Module @list不能像她期望的那样工作.

对此最好的解释是什么?她做错了什么 – 在use语句中使用预定义数组的正确方法是什么?

解决方法

这与代码执行时有关. use在编译时执行,而my @list只在运行时执行.因此,数组不存在加载模块的点.

模块Socket exports PF_INET和PF_INET6默认情况下,因此如果将其放入使用行中则无关紧要.但是Time :: HiRes does not export stuff默认情况下.

你严格得到的错误是:

Bareword “CLOCK_REALTIME” not allowed while “strict subs” in use …

这告诉我们Perl不知道CLOCK_REALTIME是一个sub,这是真的,因为当我们这样做时它没有被加载:

my @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
use Time::HiRes @consts;
printf "%d,CLOCK_MONOTONIC;

What use does需要模块并在编译时导入参数的LIST.所以它是一样的:

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,CLOCK_MONOTONIC;

__END__
0,1

像这样它可以工作,因为数组@const在相同的范围内定义,并且在Perl解释器执行它时已经可用.

由于范围界定,只需在使用前添加BEGIN块就行不通.

BEGIN {
  my @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
}

use Time::HiRes (@consts);

您可以通过在BEGIN块之外声明变量来解决问题.这样它将在下一个BEGIN块的范围内可用,并且因为BEGIN blocks are executed at compile time in FIFO order已经设置了该值.

my @consts;
BEGIN {
  @consts = qw(CLOCK_REALTIME CLOCK_MONOTONIC);
}

use Time::HiRes (@consts);
printf "%d,1

所以回顾一下:

>这是因为两件事:范围和执行顺序
>传递数组的事实不是问题 – 数组将是传递的part of the LIST>如果你不使用严格,你不能轻易找到问题>如果你在使用前添加一个BEGIN块并将我的声明放在BEGIN之外,它就可以了>如果您采用require而不是使用并自行导入,您也可以传递数组

原文链接:https://www.f2er.com/Perl/172040.html

猜你在找的Perl相关文章