2012-07-29 4 views
7

プラグマは、autodieのように、レキシカルスコープです。レキシカルスコープのプラグマ

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

が、これはuseを搭載したすべてのモジュールに適用されていますか? は、私の知る限り、使用がほぼ同じである:

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

はBEGIN

は、コンパイル時に起こる、レキシカルスコープされていないが必要なので、どのようには、その範囲についてその autodie認識して来ますか?

おかげで、autodieのバックエンドであるFatal.pmのインポート方法から

+0

あなたがやってみたいことはありますか?それとも、純粋に好奇心からですか? – ikegami

答えて

10

短い答えはpragmatic modulesが明示的にそのように動作し、機能を有効または無効にするにはコンパイル時に魔法のような内部変数$^H%^Hを使用するように書かれている字句スコープのことです。

コンパイラは、これらの変数を暗黙的にローカライズすることでその役割を果たし、その結果、コードブロックのコンパイル終了時にその値が復元時に復元されます。このようにして、それは語彙セマンティクスの基礎を提供する。

元は$^H変数のみが利用可能でした。これには、コンパイル時にいつでも使用できるコンパイラオプションを指定するビットマスクが含まれています。そのため、書くことができる唯一の字句プラグマは、$^Hの定義されたマジックビットセットを操作したものでした。

その後、%^Hハッシュが導入されました。プラグマの名前で始まるキーを使用して、このハッシュに値を格納できるようになりました。コンパイラはスカラーと同じ方法でハッシュをローカライズするため、任意のプラグマはここで自動的に有効範囲付きステータス情報を格納できます。

autodieモジュールはこれらの変数のいずれも操作しませんが、すべての難しい作業を行うモジュールFatalをサブクラス化します。 %^Hを使用して、どの演算子が致命的であったかを追跡し、コンパイラがブロックの最後にこの情報を破棄するようにします。

+1

perlpragmaの言及は良いだろう – ysth

7

、これを楽しむ:

# 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以上で動作させるために必要な余分な手順について説明しています。 – ysth

+0

ええ、私は本当に魔法の一般的な感触を伝えるためにそれの最も恐ろしい部分を示しました。それは、レキシカルプラグマを「通常の」モジュールインポートテクニックで実装できないという質問者の感情を確認したという意味での答えでした。 –

+1

しかし、それは完全に間違っています...彼らは簡単に実装することができます。 http://perldoc.perl.org/perlpragma.htmlを参照してください – ysth

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::'}がtrueでない限り何もしません。インポートは

と同等です。
sub import { $^H{'feature::qw_comments::'} = 1; } 
関連する問題