2012-07-29 92 views
7

pragmas,如autodie,根據文檔,在詞彙範圍內。詞彙範圍pragmas

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

這是否適用於裝有use所有模塊? 據我所知,採用的是幾乎是一樣的:

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

BEGIN發生在編譯時,要求不詞法範圍,所以怎麼來了,是autodie知道關於它的範圍是什麼?

感謝,

+0

有沒有你想做的事情?或者這純粹是出於好奇? – ikegami 2012-07-30 19:48:26

回答

10

簡短的回答是,詞法範圍的pragmatic modules被明確寫入的行爲是那樣,用神奇的內部變量$^H%^H在編譯時啓用和禁用功能。

編譯器通過隱式地定位這些變量來發揮作用,以便在編譯代碼塊結束時恢復它們的值,使其與開始時的代碼塊相同。這樣就提供了詞彙語義的基礎。

最初只有$^H變量可用。它包含一個位掩碼,指示在編譯期間的任何時間哪些編譯器選項可用。因爲這樣,唯一可以編寫的詞彙雜記就是那些操縱$^H中定義的魔法位的集合。

後來引入了%^H散列,現在任何編譯指示現在都可以在該散列中存儲值,其中的值以該編譯指示的名稱開頭。由於編譯器以與標量相同的方式定位哈希,所以任何編譯指示都可以在此自動存儲作用域狀態信息。

autodie模塊不會操縱這些變量中的任何一個,而是將所有艱難工作的Fatal模塊子類化。它使用%^H來跟蹤哪些運算符已致命,並依靠編譯器在塊的末尾丟棄此信息。

+1

提perlpragma會很好 – ysth 2012-07-30 00:38:51

7

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的內核糾纏在一起,並不適合普通程序員使用。

+1

不,它只解釋了使基於'%^ H'的編譯指示在5.8中工作所需的額外步驟,而不僅僅是5.10+。 – ysth 2012-07-30 00:37:52

+0

是的,我真的只顯示了它最恐怖的一部分,以表達對所涉魔法的普遍感受。這是一個答案,它證實了提問者的感受,即詞法雜記不能用「正常」模塊導入技術來實現。 – 2012-07-30 00:44:38

+1

但這是完全錯誤的......他們可以很容易地實現。見http://perldoc.perl.org/perlpragma.html – ysth 2012-07-30 02:17:35

1

這不是require這很有趣;這是編譯器在import中的作用。

大部分(全部?)編譯指示使用$^H%^H。解析器將它們定位到被解析的範圍,這意味着它將它們恢復到它們之前的值

strict爲例。它的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是用於一般用途。例如,當feature::qw_comment通過require載入解析器時會掛鉤一次,但除非$^H{'feature::qw_comments::'}爲真,否則不執行任何操作。它的進口量相當於

sub import { $^H{'feature::qw_comments::'} = 1; }