Perl の字句スコープのプラグマはどのように実装されますか?
-
13-12-2019 - |
質問
プラグマなど autodie
, ドキュメントによれば、語彙的にスコープが設定されています。
{
use autodie;
..
..
}
# Can die here
これは、ロードされたすべてのモジュールに適用されますか? use
?私の知る限りでは、 use
は次とほぼ同じです:
BEGIN {
require autodie;
autodie->import(LIST);
}
BEGIN
これはコンパイル時に発生し、require は字句スコープではありません。それで、どうですか autodie
その範囲を知っていますか?
解決
簡単に言うと、語彙の範囲が限定されているということです。 実用的なモジュール そのように動作するように明示的に書かれており、魔法の内部変数を使用します。 $^H
そして %^H
コンパイル時に機能を有効または無効にします。
コンパイラは、これらの変数を暗黙的にローカライズすることでその役割を果たし、コード ブロックのコンパイルの終了時に値が開始時の値に復元されるようにします。このようにして、語彙意味論の基礎が提供されます。
もともとは、 $^H
変数が利用可能でした。これには、コンパイル中にいつでもどのコンパイラ オプションを使用できるかを指示するビット マスクが含まれています。そのため、記述できる唯一の語彙プラグマは、定義されたマジック ビットのセットを操作するものだけでした。 $^H
.
その後、 %^H
ハッシュが導入され、プラグマはプラグマ名で始まるキーを使用してこのハッシュに値を格納できるようになりました。コンパイラはスカラーと同じ方法でハッシュをローカライズするため、どのプラグマもここに自動的にスコープされたステータス情報を格納できます。
の autodie
モジュールはこれらの変数のいずれも操作しませんが、 Fatal
すべてのハードワークを実行するモジュール。それは使用しています %^H
どの演算子が致命的になったかを追跡し、コンパイラに依存してブロックの最後でこの情報を破棄します。
他のヒント
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の内臓と深く絡み合っていて、通常のプログラマーが使うことを意味していません。
そうではありません require
それは面白い;それはプラグマが行うことです import
.
ほとんど (すべて?) プラグマは次のように使用します。 $^H
または %^H
. 。パーサーはこれらを解析対象のスコープにローカライズします。つまり、以前の値に復元します。
取る 厳しい, 、 例えば。その 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
一般的にご利用いただけます。例えば、 機能::qw_コメント によってロードされるときに、パーサーに一度フックします。 require
, 、しかしそれ以外は何もしません $^H{'feature::qw_comments::'}
それは本当です。そのインポートは次のものと同等です
sub import { $^H{'feature::qw_comments::'} = 1; }