私は簡単に次のようなことができることを知っています
sub sin {
sin($_[0]);
}
そして、すべての関数についてrefをシンブする必要があることを象徴的に参照しますが、次のようなことを行う方法があるかどうかを知りたいだけです。
{$foo}(123);
対。
&{$foo}(123);
これは機能しますが、コア機能では機能しません。
ありがとう。
私は簡単に次のようなことができることを知っています
sub sin {
sin($_[0]);
}
そして、すべての関数についてrefをシンブする必要があることを象徴的に参照しますが、次のようなことを行う方法があるかどうかを知りたいだけです。
{$foo}(123);
対。
&{$foo}(123);
これは機能しますが、コア機能では機能しません。
ありがとう。
いいえ、できません。パフォーマンス上の理由から、コンパイル時にCORE
同等の関数が宣言されていない限り、関数はシンボルテーブルを参照しません。CORE::GLOBAL
残念ながら、そのCORE::GLOBAL
関数を記述して、実際の関数の呼び出し規約をシミュレートするために適切に取得する必要があります。たとえば、大規模なCORE
ハッキングなしでは完全に再現できない機能もあります。グローバルはすべてのコードとすべてのライブラリコードに影響を与えるため、正確に正しく取得するか、デバッグエラーを非常に困難にする必要があります。autodieなどの一部のモジュールは、コア関数をラップアラウンドするために非常に長い時間を費やす必要があります。print
open
CORE::GLOBAL
しかし、ここでは、ガンロッカーと弾薬がどこにあるかをお見せしましょう...
my @return = eval "$function(\@args)";
...もちろん、これは大規模なセキュリティと保守性の穴です。しないでください。
このSOの質問を正しく読んだ場合、組み込み関数を参照することはできません。同様の問題により、シンボリック参照を使用してビルトインを呼び出すことができなくなると思います。
コードを呼び出すためのシンボリック参照の使用に関しては、代わりにディスパッチテーブルを使用することをお勧めします。例えば:
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";