杂注,像 autodie, 根据文档,是词汇范围的。

{
use autodie;
  ..
  ..
}
# Can die here

这是否适用于加载的所有模块 use?据我所知, use 几乎和:

BEGIN {
  require autodie;
  autodie->import(LIST);
}

BEGIN 在编译时发生,并且require不是词汇作用域。那么,如何是 autodie 知道它的范围吗?

有帮助吗?

解决方案

简短的回答是,词汇范围 语用模块 被明确地写成这样的行为,并使用神奇的内部变量 $^H%^H 在编译期间启用和禁用功能。

编译器通过隐式局部化这些变量来发挥作用,以便在编译代码块结束时将其值恢复到开始时的值。通过这种方式,它提供了词法语义的基础。

最初只有 $^H 变量是可用的。它包含一个位掩码,指示哪些编译器选项在编译期间随时可用。正因为如此,唯一可以写入的词法杂注是那些操纵定义的魔术位集的词法杂注。 $^H.

后来的 %^H 引入了哈希,任何杂注现在都可以在这个哈希中存储值,其中包含以杂注名称开头的键。由于编译器以与标量相同的方式本地化散列,因此任何杂注都可以在此处存储自动限定范围的状态信息。

autodie 模块不操作这些变量中的任何一个,而是子类 Fatal 完成所有艰苦工作的模块。它使用 %^H 跟踪哪些运算符已被视为致命的,并依赖编译器在块的末尾丢弃这些信息。

其他提示

从导入方法 Fatal.pm 这是后端 autodie, ,享受这个:

# Dark magic to have autodie work under 5.8
# Copied from namespace::clean, that copied it from
# autobox, that found it on an ancient scroll written
# in blood.

# This magic bit causes %^H to be lexically scoped.
$^H |= 0x020000;

所以答案是真的有一种方法可以让你的导入了解它们的词法范围,但是它深深地与perl的胆量纠缠在一起,而不是普通程序员使用的。

不是的 require 真有意思;这就是杂注的作用 import.

大多数(全部?)杂注用途 $^H%^H.解析器将它们本地化为正在解析的范围,这意味着它将它们恢复到它们之前的值

严格的, 例如。其 import 修改/修改 $^H. $^H 包含一系列标志,指示编译器如何表现。

$ perl -e'
    BEGIN { printf "%04X\n", $^H }
    {
       use strict;
       BEGIN { printf "%04X\n", $^H }
    }
    BEGIN { printf "%04X\n", $^H }
'
0100
0702
0100

$^H 是为Perl的使用而保留的,但同样是本地化的 %^H 可供一般使用。例如, 功能::qw_comment 挂钩到解析器一次,当它被加载 require, ,但不做任何事情,除非 $^H{'feature::qw_comments::'} 是真的。它的导入相当于

sub import { $^H{'feature::qw_comments::'} = 1; }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top