是否可以象征性地引用Perl核心模块?

时间:2010-05-31 11:55:30

标签: perl function symbolic-references perl-core

我知道我可以很容易地做一些像

这样的事情
sub sin {
    sin($_[0]);
}

并且象征性地引用了我需要的每个函数,但是我想知道是否有办法做某些事情,比如

{$foo}(123);

VS

&{$foo}(123);

有效,但不适用于核心功能。

感谢。

3 个答案:

答案 0 :(得分:6)

AFAIK不,你不能这样做。出于性能原因,CORE函数永远不会查看符号表,除非在编译时声明了等效的CORE::GLOBAL函数。不幸的是,您必须编写CORE::GLOBAL函数并使其正确模拟真实函数的调用约定。如果没有大量黑客,COREprint就无法完全复制某些open个函数。由于CORE::GLOBAL是全局的,因此您必须确保所有代码和所有库代码都能确保完全正确或导致非常难以调试错误。一些模块,例如autodie,必须竭尽全力包装核心功能。

但是在这里,让我告诉你枪柜和弹药的位置......

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

...当然,这是一个巨大的安全性和可维护性漏洞。不要这样做。

答案 1 :(得分:2)

如果我正确阅读this SO question,则无法引用内置函数。我怀疑类似的困难会阻止你使用符号引用来调用内置函数。

关于使用符号引用来调用代码,我建议您使用调度表。例如:

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);

答案 2 :(得分: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";