是否可以符号引用 Perl 核心模块?

发布于 2024-09-04 07:30:11 字数 262 浏览 4 评论 0原文

我知道我可以轻松地

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

为每个需要 symb ref 的函数做类似的事情,并象征性地引用它,但我只是想知道是否有一种方法可以做类似

{$foo}(123);

vs.

&{$foo}(123);

的事情,但不适用于核心函数。

谢谢。

I know I could easily do something like

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

and symbolically reference that for every function I need to symb ref, but I'd just like to know if there's a way to do something like

{$foo}(123);

vs.

&{$foo}(123);

which works, but not for core functions.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花开柳相依 2024-09-11 07:30:11

AFAIK 不,你做不到。出于性能原因,CORE 函数从不查看符号表,除非在编译时声明了等效的 CORE::GLOBAL 函数。不幸的是,您必须编写 CORE::GLOBAL 函数并使其恰到好处地模拟真实函数的调用约定。如果没有大量的黑客攻击,一些CORE功能就无法完全重现,例如printopen。由于 CORE::GLOBAL 是全局的,会影响您的所有代码和所有库代码,因此您必须确保它完全正确,否则会导致很难调试错误。某些模块,例如 autodie,必须竭尽全力来包装核心功能。

但在这里,让我向您展示枪柜和弹药在哪里......

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

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

AFAIK no, you can't do it. For performance reasons, CORE functions never look at the symbol table UNLESS an equivalent CORE::GLOBAL function has been declared at compile time. Unfortunately, you have to write that CORE::GLOBAL function and get it just right to simulate the calling conventions of the real function. Some CORE functions cannot be entirely reproduced without massive hacks, print and open for example. Since CORE::GLOBAL is global an effects all your code and all library code you have to be sure to get it exactly right or cause very hard to debug errors. Some modules, such as autodie, have to go to great lengths to wrap around core functions.

But here, let me show you where the gun locker and ammo are...

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

...of course, this is a massive security and maintainability hole. Don't do it.

一个人练习一个人 2024-09-11 07:30:11

如果我读这个问题正确的是,您不能引用内置函数。我怀疑类似的困难会阻止您使用符号引用调用内置函数。

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

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

If I read this SO question correctly, you cannot take a reference to a built-in function. I suspect that analogous difficulties will prevent you from invoking built-ins using symbolic references.

Regarding the use of symbolic references to invoke code, I would suggest that you use a dispatch table instead. For example:

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);
薄情伤 2024-09-11 07:30:11

看起来你需要在编译时重写核心函数,然后你就可以摆弄它们了。不过,我更喜欢调度哈希(或标量)方法。

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

It looks like you need to override the core functions at compile time, and then you can fiddle with them. I like the dispatch hash (or scalar) approach better, though.

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";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文