Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl';实现了哪些词汇范围的杂注?_Perl_Scope_Internals_Lexical Scope_Compiler Directives - Fatal编程技术网

Perl';实现了哪些词汇范围的杂注?

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的后端,请享受:

根据文档,Pragmas(如
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不能用“正常”的模块导入技术来实现。但这是完全错误的……它们可以很容易地实现。你有什么事想做吗?还是纯粹出于好奇?