perl - 在 Perl 中,子类为基类中的方法设置别名的正确方法是什么?

标签 perl oop goto

我只是讨厌如何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/

相关文章:

c# - 有人还在 C# 中使用 [goto] 吗?如果是,为什么?

perl - 将静态目录添加到 Mojo Lite 应用程序

multithreading - 为 Perl 推荐哪个线程池管理器?

c++ - 如何扩展一个函数

c++ - 没有 "new"C++ 的对象初始化

batch-file - (Windows 批处理)转到 if block 内的行为非常奇怪

ipython notebook 在单元格之间导航

perl - perl quine 的解释

perl - 如何改进我的 Twitter 流式爬虫?

java - 不理解 java 教程中提到的如何将接口(interface)用作 API 的主题。不要得到顿悟时刻