Perl';实现了哪些词汇范围的杂注?
根据文档,Pragmas(如Perl';实现了哪些词汇范围的杂注?,perl,scope,internals,lexical-scope,compiler-directives,Perl,Scope,Internals,Lexical Scope,Compiler Directives,根据文档,Pragmas(如autodie)是词汇范围的 { use autodie; .. .. } # Can die here 这是否适用于加载了use的所有模块? 据我所知,use几乎与以下内容相同: BEGIN { require autodie; autodie->import(LIST); } BEGIN发生在编译时,require没有词汇范围。那么,autodie是如何意识到它的范围的呢?从Fatal.pm的导入方法,它是autodie的后端,请享受:
autodie
)是词汇范围的
{
use autodie;
..
..
}
# Can die here
这是否适用于加载了use
的所有模块?
据我所知,use
几乎与以下内容相同:
BEGIN {
require autodie;
autodie->import(LIST);
}
BEGIN
发生在编译时,require没有词汇范围。那么,autodie
是如何意识到它的范围的呢?从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的精髓纠缠在一起,不适合普通程序员使用。简单的答案是,词法范围是显式编写的,并在编译时使用神奇的内部变量和来启用和禁用功能 编译器通过隐式地本地化这些变量来发挥作用,以便在编译代码块结束时将它们的值还原为开始时的值。这样,它就为词汇语义学提供了基础 最初只有
$^H
变量可用。它包含一个位掩码,指示在编译过程中的任何时候哪些编译器选项可用。因此,唯一可以编写的词汇pragma是那些在$^H
中操纵已定义的魔法位集的pragma
后来引入了%^H
散列,现在任何pragma都可以使用以pragma名称开头的键在此散列中存储值。由于编译器以与标量相同的方式对哈希进行本地化,因此任何pragma都可以在此处自动存储作用域状态信息
autodie
模块不处理这两个变量中的任何一个,而是对完成所有艰苦工作的模块进行子类化。它使用%^H
来跟踪哪些操作符被设置为致命的,并依靠编译器在块的末尾丢弃这些信息。有趣的不是需要;这是pragma在import
中所做的
大多数(全部?)杂注使用$^H
或%^H
。解析器将它们定位到被解析的范围,这意味着它将它们恢复到以前的值
比如说。它的导入
修改$^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
也可供一般使用。例如,当解析器由require
加载时,钩住解析器一次,但除非$^H{'feature::qw_comments::'}
为true,否则不会执行任何操作。它的重要性相当于
sub import { $^H{'feature::qw_comments::'} = 1; }
不,它只解释了使基于%^H
的pragmas在5.8中工作所需的额外步骤,而不仅仅是5.10+。是的,我只是展示了其中最可怕的部分,以传达对所涉及的魔法的一般感觉。这是一个回答,从某种意义上说,它证实了提问者的感觉,即词汇pragmas不能用“正常”的模块导入技术来实现。但这是完全错误的……它们可以很容易地实现。你有什么事想做吗?还是纯粹出于好奇?