Perl的词法范围的pragma是如何实现的?

sno*_*kin 8 perl scope internals compiler-directives lexical-scope

编译指示一样autodie,根据文档,是词法范围的.

{
use autodie;
  ..
  ..
}
# Can die here
Run Code Online (Sandbox Code Playgroud)

这适用于所有加载的模块use吗?据我所知,use几乎相同:

BEGIN {
  require autodie;
  autodie->import(LIST);
}
Run Code Online (Sandbox Code Playgroud)

BEGIN在编译时发生,并且require不是词法范围.那怎么autodie知道它的范围呢?

Bor*_*din 11

简短的回答是,词法范围的实用模块被明确地编写为以这种方式运行,并使用神奇的内部变量$^H%^H在编译期间启用和禁用功能.

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

最初只有$^H变量可用.它包含一个位掩码,用于指示在编译期间随时可用的编译器选项.因此,可以编写的唯一词汇编译指示是操纵已定义的魔术位集的编曲$^H.

稍后%^H引入了哈希,并且任何pragma现在都可以使用以pragma名称开头的键在此哈希值中存储值.因为编译器以与标量相同的方式对散列进行本地化,所以任何pragma都可以在此处存储自动作用域状态信息.

autodie模块不会操纵这些变量中的任何一个,而是对Fatal完成所有艰苦工作的模块进行子类化.它用于%^H跟踪哪些运算符已成为致命的,并依赖于编译器在块结束时丢弃此信息.


Ala*_*rry 8

从导入方法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;
Run Code Online (Sandbox Code Playgroud)

所以答案是真的有办法让你的进口意识到自己的词汇范围,但它深深地纠缠用Perl的胆量,而不是意味着普通程序员使用.

  • 但这完全错了......他们很容易实现.见http://perldoc.perl.org/perlpragma.html (2认同)