1

私は簡単に次のようなことができることを知っています

sub sin {
    sin($_[0]);
}

そして、すべての関数についてrefをシンブする必要があることを象徴的に参照しますが、次のようなことを行う方法があるかどうかを知りたいだけです。

{$foo}(123);

対。

&{$foo}(123);

これは機能しますが、コア機能では機能しません。

ありがとう。

4

3 に答える 3

6

いいえ、できません。パフォーマンス上の理由から、コンパイル時にCORE同等の関数が宣言されていない限り、関数はシンボルテーブルを参照しません。CORE::GLOBAL残念ながら、そのCORE::GLOBAL関数を記述して、実際の関数の呼び出し規約をシミュレートするために適切に取得する必要があります。たとえば、大規模なCOREハッキングなしでは完全に再現できない機能もあります。グローバルはすべてのコードとすべてのライブラリコードに影響を与えるため、正確に正しく取得するか、デバッグエラーを非常に困難にする必要があります。autodieなどの一部のモジュールは、コア関数をラップアラウンドするために非常に長い時間を費やす必要があります。printopenCORE::GLOBAL

しかし、ここでは、ガンロッカーと弾薬がどこにあるかをお見せしましょう...

my @return = eval "$function(\@args)";

...もちろん、これは大規模なセキュリティと保守性の穴です。しないでください。

于 2010-05-31T21:14:09.443 に答える
2

この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);
于 2010-05-31T14:33:54.920 に答える
0

コンパイル時にコア関数をオーバーライドする必要があるようです。そうすれば、それらをいじることができます。ただし、ディスパッチハッシュ(またはスカラー)アプローチの方が好きです。

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";
于 2010-06-01T06:56:34.147 に答える