2014-09-20 26 views
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

的问题是:

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

EDIT也许这个问题可以简化为下面的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(); 
在这两种情况下

(例如“纯”重新定义,并用“覆盖”重新定义)打印:

another some from My2 

所以,唯一不同的是要求在someoverridesuper()的可能性?和抱歉,如果我错过了一些基本knowlegde ...;(

回答

4

在梅森override实现方法修改override在驼鹿,麋鹿的override是用于覆盖父方法标准OO方法的语法糖,但有一些限制,如果方法带有参数从Moose docs for override:。

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

super()调用几乎与调用 $self->SUPER::display_name不同的是,该参数 传递给父类的方法总是与传递给方法修饰符的 一样,并且无法更改。所有参数 传递到super()将被忽略,因为在调用 super()之前对@_所做的任何更改都将被忽略。

从你上面的穆斯类举一个例子,让我们给some一些参数:创建My对象并调用$obj->some('pip', 'pop')

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

输出:

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可以更改。

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

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和标准方法重定义之间的区别。

+0

所以唯一的区别是:当使用'<%override ...>'我可以调用'<% super() %>',但是当简单重新定义方法时,我不能调用'<% super() %>'? – cajwine 2014-09-21 08:06:00

+0

编辑这个问题 - 也许它更清晰的是“梅森”。 – cajwine 2014-09-21 09:01:42

+1

我会更新我的答案。 – 2014-09-21 09:27:38