我怎么知道哪个别名用于调用别名子例程? caller
给出了原始的 sub
-name,但我希望看到调用时使用的名称。
例子:
use 5.010;
sub x_y_z {
return ( caller(0) )[3];
}
*foo_bar_baz = \&x_y_z;
say x_y_z(); # x_y_z
say foo_bar_baz(); # x_y_z, but need foo_bar_baz
编辑以解决 XY 问题
我添加另一个例子来展示我更深层次的意图。我想创建调度表来路由一些任务:
my $dispatch = {
x => {
y => {
z => sub {
&x_y_z;
},
}
},
a => {
b => {
c => {
d => sub {
&a_b_c_d;
},
}
}
}
}
sub foo {
my @arg = ( split '_', ( split( '::', ( caller(0) )[3] ) )[1] );
return @arg;
}
*x_y_z = \&foo;
*a_b_c_d = \&foo;
正如您想象的那样,这棵树可能会长得很大。现在 dispatch-tree 中的许多叶子都需要基本相同的 sub,它们只是它们被调用(命名)的方式不同,我希望只有一个 sub 并为特定任务取别名。
最佳答案
您尝试做的事情在 Perl 的数据模型中是根本不可能的。别名只是一个别名,而不是一个有自己身份的对象。
请注意,可以复制一个子程序并为其指定一个新名称,例如:
use Sub::Name;
*x_y_z = subname x_y_z => \&foo;
但您必须手动执行此操作。
除了堆栈跟踪之外,依赖子名不是一个好主意。尝试在这些名称之上构建任何逻辑可能会导致难以调试的困惑,而不是优雅的软件。
最好将路由名称作为显式参数传递到处理程序函数,并创建一个辅助函数来抽象必要的管道。例如:
my %routes;
sub route {
my ($name, $handler) = @_;
$routes{$name} = sub { $handler->($name => @_) };
return;
}
sub common_handler { ... }
route a_b_c => \&common_handler;
route x_y_z => \&common_handler;
route foo_bar => sub {
my ($route) = @_;
say "Custom handler invoked for route $route";
};
$routes{$name}->(@args);
如果绝对必要,您当然可以实现这样的 route
函数,以便它将处理程序安装为命名子例程。但那时你正在构建某种框架,如 Moo(se),而不是普通的 Perl 模块。
关于perl - 如何获取被调用的别名子程序的名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51310313/