我只是讨厌如何调用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');
Run Code Online (Sandbox Code Playgroud)
这是我认为它应该工作,我不能看到任何问题(比如说,如果我想继承My::Merhaba:子类不需要知道任何事情merhaba).
写作会更好/更正确吗?
sub merhaba {
my $self = shift;
return $self->hello(@_);
}
Run Code Online (Sandbox Code Playgroud)
使用goto &NAME方法名称别名的优点/缺点是什么?有没有更好的办法?
注意:如果你有回应的冲动goto是邪恶不要这样做,因为Perl的使用与goto你的想法不同.
Eri*_*rom 10
你的方法goto是正确的,因为它将确保caller/ wantarray等继续正常工作.
我会像这样设置新方法:
sub merhaba {
if (my $method = eval {$_[0]->can('hello')}) {
goto &$method
} else {
# error code here
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您不想使用继承,可以从调用代码将新方法添加到现有包中:
*My::Hello::merhaba = \&My::Hello::hello;
# or you can use = My::Hello->can('hello');
Run Code Online (Sandbox Code Playgroud)
然后你可以打电话:
My::Hello->merhaba('StackOverflow');
Run Code Online (Sandbox Code Playgroud)
并获得所需的结果.
无论哪种方式都可行,继承路由更易于维护,但将方法添加到现有包将导致更快的方法调用.
编辑:
正如评论中所指出的,有一些情况是全局赋值将与继承发生冲突,所以如果有疑问,请使用第一种方法(在子包中创建一个新方法).
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'";
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
555 次 |
| 最近记录: |