4

使用Mason2。有 3 个组件。

/Base.mc
/tmp/Base.mc
/tmp/index.mc

/tmp/index.mc一个内容:

hello from <% $m->request_path %></br>
<% $.Some %>

$.Some在 中定义的方法/Base.mc

<%augment wrap><% inner() %></%augment>

<%method Some>
The default "Some" method defined in the <% __PACKAGE__ %>
</%method>

/tmp/Base.mc仅包含

<%augment wrap><% inner() %></%augment>

要求/tmp/index打印:

hello from /tmp/index
The default "Some" method defined in the MC0::Base_mc

现在将Some方法添加到/tmp/Base.mc

<%method Some>
Redefined "Some" method in <% __PACKAGE__ %>
</%method>

再次请求/tmp/index,它打印:

hello from /tmp/index
Redefined "Some" method in MC0::tmp_Base_mc

它尊重Some包装中重新定义的方法/tmp/Base.mc

问题是:

如果 Mason 允许重新定义上述方法,那么 的目的是<%override method>什么?有<%override Some>什么不同吗?(当我测试时,它打印相同)。

编辑也许问题可以简化为以下 perl 代码。

use 5.014;
use warnings;

package My;
use Moose;
sub some { say "some from " . __PACKAGE__ }

package My2;
use Moose;
extends 'My';
sub some { say "another some from " . __PACKAGE__ }
#the above line is an correct way to refefine a sub "some"?
#so don;t need to use the
#override 'some' => sub { say "another some from " . __PACKAGE__ };

package main;
use My2;
my $m = My2->new();
$m->some();

在这两种情况下(例如“plain”重新定义和用“override”重新定义)打印:

another some from My2

所以,唯一的区别是调用withsuper()的可能性?抱歉,如果我错过了一些基本知识... ;(someoverride

4

1 回答 1

4

override在 Mason 中实现overrideMoose 中的方法修饰符;Mooseoverride是用于覆盖父方法的标准 OO 方法的语法糖,但如果该方法带有参数,则有一些限制。来自Moose 文档override

override 'display_name' => sub {
    my $self = shift;
    return super() . q{, } . $self->title(); };

调用 tosuper()几乎与调用 相同 $self->SUPER::display_name。不同之处在于传递给超类方法的参数将始终与传递给方法修饰符的参数相同,并且不能更改。传递给的所有参数都将被忽略,就像调用之前 super()所做的任何更改一样。@_super()

举一个上面的 Moose 类的例子,让我们给出some一些论点:

package My;
use Moose;
sub some {
    my $self = shift;
    say "   " . __PACKAGE__ . " method 'some' args: " . join " ", @_;
}

创建My对象并调用后的输出$obj->some('pip', 'pop')

My method 'some' args: pip pop

现在让我们看看My2。定义some为普通的封装方法:

package My2;
use Moose;
extends 'My';
sub some {
    my $self = shift;
    say "   # running 'some'";
    say "   " . __PACKAGE__ . " method 'some' args: " . join " ", @_;
    @_ = reverse @_;
    say "   # running \$self->SUPER::some with no args";
    $self->SUPER::some();
    say "   # running \$self->SUPER::some with reversed args";
    $self->SUPER::some( @_ );
    say "   # running super() with no args";
    super();
    say "   # running super() with reversed args";
    super( @_ );
};

创建一个My2对象,然后调用$obj->some('pip','pop'). 输出:

# running 'some'
My2 method 'some' args: pip pop
# running $self->SUPER::some with no args
My method 'some' args: 
# running $self->SUPER::some with reversed args
My method 'some' args: pop pip
# running super() with no args
# running super() with reversed args
Arguments passed to super() are ignored at test.pl line 29.

注意事项:

  • super()在重新定义的方法中什么都不做;
  • super()不能接受论据;
  • $self->SUPER::some不会自动传递任何参数;
  • $self->SUPER::some可以更改参数。

现在使用重新定义some方法override

override 'some' => sub {
    my $self = shift;
    say "   # running 'some'";
    say "   " . __PACKAGE__ . " method 'some' args: " . join " ", @_;
    @_ = reverse @_;
    say "   # running \$self->SUPER::some with no args";
    $self->SUPER::some();
    say "   # running \$self->SUPER::some with reversed args";
    $self->SUPER::some( @_ );
    say "   # running super() with no args";
    super();
    say "   # running super() with reversed args";
    super( @_ );
};

输出:

# running 'some'
My2 method 'some' args: pip pop
# running $self->SUPER::some with no args
My method 'some' args: 
# running $self->SUPER::some with reversed args
My method 'some' args: pop pip
# running super() with no args
My method 'some' args: pip pop
# running super() with reversed args
Arguments passed to super() are ignored at test.pl line 29.
My method 'some' args: pip pop

注意事项:

  • super()方法现在可以正确调用超类方法some
  • super()不能接受论据;它会自动使用@_您传递给子类方法的相同方法;
  • $self->SUPER::some可以更改参数。

这基本上取决于您如何在子类中实现方法,但这应该说明了标准方法重override定义和标准方法重定义之间的区别。

于 2014-09-21T07:55:23.777 回答