使用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();
在这两种情况下(例如“普通”重新定义并重新定义“覆盖”)打印:
another some from My2
那么,唯一的区别是可以使用super()
调用some
中的override
吗?对不起,如果我错过了一些基本的知识......;(
答案 0 :(得分:4)
override
在Moose中实现方法修饰符override
; Moose的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()
被称为。{/ p>
举一个上述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
和标准方法重新定义之间的差异。