我将要在运行时调用的子例程的名称保存在名为 $action 的变量中。然后我用它在正确的时间调用该子程序:
&{\&{$action}}();
工作正常。我唯一不喜欢的是它很丑,每次我这样做时,我都觉得有义务为下一个开发人员添加评论:
# call the sub by the name of $action
有人知道这样做的更漂亮的方法吗?
更新:这里的想法是避免每次添加新的可调用子项时都必须维护调度表,因为我是唯一的开发人员,我不担心其他程序员遵循或不遵循“规则”。为了我的方便牺牲了一点安全性。相反,我的调度模块会检查 $action 以确保 1) 它是定义的子例程的名称,而不是使用 eval 运行的恶意代码,2) 它不会运行任何以下划线开头的子程序,这将是通过此命名约定标记为仅供内部使用的子程序。
对这种方法有什么想法吗?我总是会忘记将调度表中的子例程列入白名单,而且我的客户宁愿我犯“它有效”而不是“它非常安全”的错误。 (开发应用程序的时间非常有限)
最终更新:我想我毕竟已经决定了调度表。虽然我很好奇是否有人读过这个问题,是否曾试图废除一个,以及他们是如何做到的,但我必须屈服于这里的集体智慧。感谢大家,有很多很棒的回复。
与其将子例程名称存储在变量中并调用它们,更好的方法是使用子例程引用的哈希值(也称为调度表 https://en.wikipedia.org/wiki/Dispatch_table.)
my %actions = ( foo => \&foo,
bar => \&bar,
baz => sub { print 'baz!' }
...
);
然后你就可以轻松地调用正确的方法:
$actions{$action}->();
您还可以添加一些检查以确保$action
是哈希中的有效密钥,等等。
一般来说,您应该避免符号引用(您现在正在做的事情),因为它们会导致各种问题。此外,使用真正的子程序引用将与strict
打开。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)