perl - 如何优雅地调用名称保存在变量中的 Perl 子例程?

标签 perl

我将要在运行时调用的子例程的名称保存在名为 $action 的变量中。然后我用它在正确的时间调用该子程序:

&{\&{$action}}();

工作正常。我唯一不喜欢的是它很丑,每次我这样做时,我都觉得有责任为下一个开发人员添加评论:

# call the sub by the name of $action

有人知道更漂亮的方法吗?

<小时/>

更新:这里的想法是避免每次添加新的可调用子项时都必须维护调度表,因为我是唯一的开发人员,所以我不担心其他程序员遵循或不遵循“规则”。为了我的方便牺牲了一点安全性。相反,我的调度模块会检查 $action 以确保 1) 它是定义的子例程的名称,而不是使用 eval 运行的恶意代码,2) 它不会运行任何以下划线开头的子程序,这将是通过此命名约定标记为仅供内部使用的子程序。

对这种方法有什么想法吗?我总是会忘记将调度表中的子例程列入白名单,而且我的客户宁愿我犯“它有效”而不是“它非常安全”的错误。 (开发应用程序的时间非常有限)

<小时/>

最终更新:我想我已经决定了调度表。虽然我很好奇读到这个问题的人是否曾经试图废除一个,以及他们是如何做到的,但我必须屈服于这里的集体智慧。感谢大家,许多精彩的回复。

最佳答案

与其将子例程名称存储在变量中并调用它们,更好的方法是使用子例程引用的哈希值(也称为 dispatch table 。)

my %actions = ( foo => \&foo,
                bar => \&bar,
                baz => sub { print 'baz!' } 
                ... 
              );

然后您就可以轻松调用正确的方法:

$actions{$action}->();

您还可以添加一些检查以确保 $action 是哈希中的有效键,等等。

一般来说,您应该避免符号引用(您现在正在做的事情),因为它们会导致各种问题。此外,使用真正的子例程引用将在 strict 打开的情况下工作。

关于perl - 如何优雅地调用名称保存在变量中的 Perl 子例程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1915616/

相关文章:

regex - Perl正则表达式定界符/.../和#...#之间的区别

perl - 当 my() 有条件时会发生什么?

perl - 在 Perl 中,如何用空格填充字符串的一部分?

Perl/CGI 脚本在大量上传时失败

linux - Bash 中的局部变量与 Perl 中的一样吗?

string - 在 Perl 中,为什么将散列与字符串连接在一起会给出看起来像分数的结果?

perl - 如何使用不断变化的系统时间测试 Perl 应用程序?

perl - 如何在 64 位 CentOS 系统上为 32 位自定义 Perl 构建 32 位 XS 模块?

python - 如何使用文件名创建文件夹,然后将文件移动到文件夹中?

Perl 系统命令到 Windows NUL 或/dev/null