8

autodieドキュメントによると、のようなプラグマはレキシカルスコープです。

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

これは、ロードされたすべてのモジュールに適用されますuseか? 私の知る限り、次useのものとほぼ同じです。

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

BEGINコンパイル時に発生し、require はレキシカル スコープではありません。では、その範囲をどのようにautodie認識していますか?

4

3 に答える 3

11

手短に言えば、レキシカル スコープのプラグマティック モジュールは明示的にそのように動作するように記述されており、コンパイル時に魔法の内部変数$^Hを使用して機能を有効または無効にします。%^H

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

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

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

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

于 2012-07-29T19:23:01.737 に答える
8

Fatal.pmのバックエンドであるimport メソッドから、これ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 の内臓と深く絡み合っており、通常のプログラマが使用することを意図したものではありません。

于 2012-07-29T19:08:48.520 に答える
1

それはrequire興味深いことではありません。それは、プラグマが で行うことimportです。

ほとんどの (すべて?) プラグマは$^Horを使用します%^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

$^HPerl の使用のために予約されていますが、同様にローカライズされた%^Hものは一般的な使用に利用できます。たとえば、feature::qw_commentは、 によってロードされたときにパーサーに 1 回フックしますが、true でrequireない限り何もしません$^H{'feature::qw_comments::'}。インポートは同等です

sub import { $^H{'feature::qw_comments::'} = 1; }
于 2012-07-30T01:13:21.677 に答える