如何在加载模块之前定义环境变量?

How to define an environment variable before loading modules?

我使用 AnyEvent::DNS 模块。

我想禁用 IPv6,以便解析器只请求 A 记录。

AnyEvent::DNS,使用环境变量$ENV{PERL_ANYEVENT_PROTOCOLS}

但是设置变量不起作用;解析器仍然发送两个请求 AAAAA

来自 AnyEvent::DNS 的代码:

our %PROTOCOL; # (ipv4|ipv6) => (1|2), higher numbers are preferred

BEGIN {
   ...;
   my $idx;
   $PROTOCOL{$_} = ++$idx
      for reverse split /\s*,\s*/,
             $ENV{PERL_ANYEVENT_PROTOCOLS} || "ipv4,ipv6";
}

如何在加载模块前定义环境变量?

由于检查环境变量的代码在 BEGIN 块中,一旦 Perl 编译器到达它,它将立即 运行。

当 Perl 开始编译您的脚本时,它首先检查 use 语句。因此,当您 use AnyEvent::DNS 时,Perl 加载该模块并解析该文件。 BEGIN 块在那个阶段执行,而方法中的代码只会被编译,不会被执行。

所以如果你有类似下面的东西,你上面显示的代码将是 运行 在你设置那个变量之前。

use strict;
use warnings;
use AnyEvent::DNS;

$ENV{PERL_ANYEVENT_PROTOCOLS} = 'ipv4';
...

有两种方法可以避免这种情况。

您可以在加载 AnyEvent::DNS 之前将作业放在您自己的 BEGIN 块中。这样就会先设置。

use strict;
use warnings;

BEGIN {
    $ENV{PERL_ANYEVENT_PROTOCOLS} = 'ipv4';
}

use AnyEvent::DNS;

或者,您可以使用从 shell.

为它设置的环境变量来调用您的程序
$ PERL_ANYEVENT_PROTOCOLS=ipv4 perl resolver.pl

第二个更便携,以防您以后希望它支持 IPv6。

阅读 perlmod 中关于 BEGIN 的更多信息。