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

是否可以象征性地引用Perl核心模块?,perl,function,symbolic-references,perl-core,Perl,Function,Symbolic References,Perl Core,我知道我可以很容易地做类似的事情 sub sin { sin($_[0]); } {$foo}(123); 对于每个函数,我都需要符号化ref,但我想知道是否有一种方法 sub sin { sin($_[0]); } {$foo}(123); vs 这是可行的,但不适用于核心功能 谢谢。如果我读对了,您就不能引用内置函数。我怀疑类似的困难会阻止您使用符号引用调用内置函数 关于使用符号引用来调用代码,我建议您改用分派表。例如: use strict; use warning

我知道我可以很容易地做类似的事情

sub sin {
    sin($_[0]);
}
{$foo}(123);
对于每个函数,我都需要符号化ref,但我想知道是否有一种方法

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

这是可行的,但不适用于核心功能

谢谢。

如果我读对了,您就不能引用内置函数。我怀疑类似的困难会阻止您使用符号引用调用内置函数

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

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;

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

对不起,不,你不能这么做。出于性能原因,
CORE
函数从不查看符号表,除非在编译时声明了等效的
CORE::GLOBAL
函数。不幸的是,您必须编写
CORE::GLOBAL
函数,并正确地模拟实际函数的调用约定。一些
核心
功能如果没有大规模的黑客攻击就无法完全复制,例如
打印
打开
。由于
CORE::GLOBAL
是全局的,它会影响您的所有代码和所有库代码,因此您必须确保它完全正确,否则会导致很难调试错误。一些模块,例如,必须走很长的路来包装核心功能

但是在这里,让我告诉你枪柜和弹药在哪里

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

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

哦,不,你不能这样做。出于性能原因,
CORE
函数从不查看符号表,除非在编译时声明了等效的
CORE::GLOBAL
函数。不幸的是,您必须编写
CORE::GLOBAL
函数,并正确地模拟实际函数的调用约定。一些
核心
功能如果没有大规模的黑客攻击就无法完全复制,例如
打印
打开
。由于
CORE::GLOBAL
是全局的,它会影响您的所有代码和所有库代码,因此您必须确保它完全正确,否则会导致很难调试错误。一些模块,例如,必须走很长的路来包装核心功能

但是在这里,让我告诉你枪柜和弹药在哪里

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

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

看起来您需要在编译时重写核心函数,然后您可以处理它们。不过,我更喜欢分派散列(或标量)方法

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

看起来您需要在编译时重写核心函数,然后再处理它们。不过,我更喜欢分派散列(或标量)方法

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

您希望通过这样做实现什么?也许有不止一种方法可以做到这一点。为什么要使用符号引用,这需要禁用
使用strict
?为什么不使用代码引用而不是符号引用?重申daxim的问题,你更大的目标是什么?这意味着你正在获取一个字符串并将其用作子引用。如果手动将该字符串设置为“attack”,那么将其设置为\&attack也同样容易。如果你是从用户那里得到的,那么你就有安全风险。在任何一种情况下,在将该字符串用作符号引用之前,都必须完全确定该字符串是如何设置的,并且该字符串是安全的。默认情况下,使用严格禁止对sub的符号引用的原因是,当您打算对coderef进行解引用时,可能会意外地解引用字符串,并且意外地执行了一些任意代码。@Blaise另外,符号引用是一个安全漏洞,因为字符串可能来自用户输入,或者受到用户输入的影响。这在使用符号引用作为分派表的CGI代码中很常见。它们还使您的代码更难理解。您无法再看到每个子例程或全局变量的使用位置。每次使用符号引用都可能触及代码中的任何地方。答案仍然是使用散列来控制和限制可能性<代码>$dispatch{attack}=\&attack$调度{$foo}->()您希望通过这样做实现什么?也许有不止一种方法可以做到这一点。为什么要使用符号引用,这需要禁用
使用strict
?为什么不使用代码引用而不是符号引用?重申daxim的问题,你更大的目标是什么?这意味着你正在获取一个字符串并将其用作子引用。如果手动将该字符串设置为“attack”,那么将其设置为\&attack也同样容易。如果你是从用户那里得到的,那么你就有安全风险。在任何一种情况下,在将该字符串用作符号引用之前,都必须完全确定该字符串是如何设置的,并且该字符串是安全的。默认情况下,使用严格禁止对sub的符号引用的原因是,当您打算对coderef进行解引用时,可能会意外地解引用字符串,并且意外地执行了一些任意代码。@Blaise另外,符号引用是一个安全漏洞,因为字符串可能来自用户输入,或者受到用户输入的影响。这在使用符号引用作为分派表的CGI代码中很常见。它们还使您的代码更难理解。您无法再看到每个子例程或全局变量的使用位置。每次使用符号引用都可能触及代码中的任何地方。答案仍然是使用散列来控制和限制可能性<代码>$dispatch{attack}=\&attack$调度{$foo}->()