我只是讨厌如何将
CGI::Application的CGI对象的访问者称为查询.
我希望我的实例类能够使用名为cgi的访问器来获取与我的CGI :: Application子类的当前实例相关联的CGI对象.
这是我所做的一个独立的例子:
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');
这是正常工作,因为我认为应该和我看不到任何问题(比如说,如果我想继承我的:: Merhaba:子类不需要知道任何关于merhaba).
写得更好/更正确吗?
sub merhaba { my $self = shift; return $self->hello(@_); }
使用goto &NAME
为了混淆方法名称的目的有哪些优点/缺点?有没有更好的办法?
注意:如果你有希望回应goto是邪恶的,不要这样做,因为Perl的goto的使用与你所想的不同.
解决方法
您使用goto的方法是正确的,因为它将确保来电者/想法等保持正常工作.
我会设置这样的新方法:
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'"; }