我只是讨厌如何CGI::Application CGI
的访问器对象被称为 query
.
我希望我的实例类能够使用名为 cgi
的访问器获取 CGI
与我的当前实例关联的对象 CGI::Application
子类。
这是我正在做的事情的一个独立示例:
package My::Hello;
sub hello {
my $self =shift;
print "Hello @_\n";
}
package My::Merhaba;
use base 'My::Hello';
sub merhaba {
goto sub { shift->hello(@_) };
}
package main;
My::Merhaba->merhaba('StackOverflow');
这是我认为应该的工作,我看不到任何问题(例如,如果我想从
My::Merhaba
继承:子类不需要知道关于 merhaba
的任何信息)。写起来会更好/更正确吗
sub merhaba {
my $self = shift;
return $self->hello(@_);
}
使用
goto &NAME
的优缺点是什么?为了给方法名称取别名?有更好的方法吗?注:如果您想回复
goto
不要这样做是邪恶的,因为这种使用 Perl 的 goto
和你想的不一样。
最佳答案
您的方法 goto
是正确的,因为它会确保 caller
/wantarray
等保持正常工作。
我会像这样设置新方法:
sub merhaba {
if (my $method = eval {$_[0]->can('hello')}) {
goto &$method
} else {
# error code here
}
}
或者,如果您不想使用继承,则可以从调用代码将新方法添加到现有包中:
*My::Hello::merhaba = \&My::Hello::hello;
# or you can use = My::Hello->can('hello');
然后你可以打电话:
My::Hello->merhaba('StackOverflow');
并得到想要的结果。
无论哪种方式都可行,继承路由更易于维护,但将方法添加到现有包会导致更快的方法调用。
编辑:
正如评论中所指出的,在某些情况下,glob 赋值会与继承发生冲突,因此如果有疑问,请使用第一种方法(在子包中创建新方法)。
Michael Carman 建议将这两种技术结合到一个自我重新定义的函数中:
sub merhaba {
if (my $method = eval { $_[0]->can('hello') }) {
no warnings 'redefine';
*merhaba = $method;
goto &merhaba;
}
die "Can't make 'merhaba' an alias for 'hello'";
}
关于perl - 在 Perl 中,子类为基类中的方法设置别名的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2266865/