在Perl中,子类在基类中别名的方法是什么?

我只是讨厌如何将 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'";
}

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...