Perlコアモジュールを象徴的に参照することは可能ですか?
-
05-10-2019 - |
質問
私は簡単にできることを簡単にできることを知っています
sub sin {
sin($_[0]);
}
そして、すべての関数について、私はsymb refをsymbにする必要があることを象徴的に参照しますが、私はただのことをする方法があるかどうかを知りたいです
{$foo}(123);
vs。
&{$foo}(123);
これは機能しますが、コア関数用ではありません。
ありがとう。
解決
Afaikいいえ、あなたはそれをすることはできません。パフォーマンスの理由から、 CORE
関数は、同等の場合を除き、シンボルテーブルを決して見ません CORE::GLOBAL
機能はコンパイル時に宣言されています。残念ながら、あなたはそれを書かなければなりません CORE::GLOBAL
機能と、実際の関数の呼び出し規則をシミュレートするのが適切に取得されます。いくつかの CORE
関数は、大規模なハックなしでは完全に複製することはできません。 print
と open
例えば。以来 CORE::GLOBAL
すべてのコードとすべてのライブラリコードは、グローバルな影響ですあなたはそれを確実に取得する必要があります まさに エラーをデバッグするのが非常に難しいか、非常に困難です。などの一部のモジュール オートディー, 、コア関数を包み込むためには、かなりの長さに進む必要があります。
しかし、ここでは、銃のロッカーと弾薬がどこにあるかを見せてください...
my @return = eval "$function(\@args)";
...もちろん、これは大規模なセキュリティと保守性の穴です。それをしないでください。
他のヒント
読んだら これはとても質問です 正しく、組み込み関数への参照を取得することはできません。類似の難しさは、象徴的な参照を使用してビルドインを呼び出すことを妨げると思われます。
コードを呼び出すためのシンボリック参照の使用に関して、代わりにディスパッチテーブルを使用することをお勧めします。例えば:
use strict;
use warnings;
sub sin_deg { sin $_[0] * atan2(1, 1) / 45 }
my %dt = (
sin_deg => \&sin_deg,
attack => sub { print "Attacking: @_\n" },
);
print $dt{sin_deg}->(60), "\n";
$dt{attack}->(1, 2, 3);
コンパイル時間でコア関数をオーバーライドする必要があるように見えます。その後、それらをいじることができます。ただし、ディスパッチハッシュ(またはスカラー)アプローチが好きです。
use strict;
use warnings;
our $s;
BEGIN {
*CORE::GLOBAL::sin= sub { sin($_[0])*2 };
*CORE::GLOBAL::cos= sub { cos($_[0])*2 };
our $s= *CORE::GLOBAL::sin;
}
*CORE::GLOBAL::sin= *CORE::GLOBAL::cos;
print sin(0.01)."\n";
print $s->(0.01)."\n";