首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调用SUPER::new()

调用SUPER::new()
EN

Stack Overflow用户
提问于 2012-06-08 14:58:50
回答 2查看 5K关注 0票数 6

我看到了在派生类中实现new方法的两种方法。

方法一:

代码语言:javascript
复制
sub new {
    my $invocant = shift;
    my $class   = ref($invocant) || $invocant; 
    my $self = {};
    bless($self, $class);
    $self = $self->SUPER::new( @_ );
    return($self);
}

方法二:

代码语言:javascript
复制
sub new {
  my $self = shift;
  my $class = ref($self) || $self;
  return $self if ref $self;
  my $base_object = $class->SUPER::new(@_);
  return bless ($base_object, $class);
}

我不知道这有什么区别。有人能解释一下吗?

从您的评论和回答中,我可以看到ref()部分是不好的。

但是SUPER::new(@_)的使用呢?在第一个示例中,哈希and被授予派生类,然后调用该对象的SUPERnew并将其保存到同一个对象中。

另一方面,在第二个示例中,从类的SUPERnew方法创建一个基本对象,这个对象被赋予新的类。

这两种方式有什么区别?它看起来像是第一个用基对象覆盖对象。第二种似乎是“双重祝福”。我很困惑。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-08 15:20:50

更新

你问:

这两种方式有什么区别?它看起来像是第一个用基对象覆盖对象。第二种似乎是“双重祝福”。我很困惑。

振作起来。您所展示的两种方法本身都是混乱的,两者都不应该被模仿。

方法将类DerivedClass的对象赋值,然后使用该对象调用某些AncestorClass的分配器/构造函数,替换自身。现在,AncestorClass::new可能也使用了不幸的ref($yuck) || $yuck成语,这意味着新对象将被祝福为DerivedClass。因此,使用一个DerivedClass对象来构造另一个对象来替换它。可疑。

如果接收方是对象,则方法2返回其接收器($self)。(注意,当ref($self)只需要检查一次时,它会被检查两次。)也就是说,$o->new()在方法2下返回完全相同的$o。如果接收方不是对象而是类名,也就是说,如果我们调用了DerivedClass->new,则调用AncestorClass::new。但是,超类‘方法’的第一个参数是‘派生类’,并且假定超类不会硬编码它的blessed包名,因此后续的重新祝福是没有意义的。

只是不要担心这些例子。相反,请咨询佩洛布围观的安全和理智的用途超级。

原始答案

啊,我的眼睛!

正如daxim所指出的,方法一是允许从现有对象的同一个类构造对象的一种令人不快的方法:

代码语言:javascript
复制
my $o1 = MethodOne->new();
my $o2 = $o1->new();        # $o2 is a clone of $o1.  No, wait, it isn't!
                            # It's a brand new, "empty" object.  Ha,
                            # fooled you.

第二种方法(我认为)是对这种令人困惑的做法的解决办法。如果调用,则方法2将返回完全相同的对象

代码语言:javascript
复制
my $o1 = MethodTwo->new();
my $o2 = $o1->new();         # $o2 is a new MethodTwo.  No, wait, it isn't!
                             # It's a brand new object.  No, wait, it isn't!
                             # It's a /exactly the same object/ as $o1.  Ha,
                             # fooled you.

也不要用。)在某些应用程序中,上述任何一种语义都是完全合理的。我只是不想在那些应用中把那个方法命名为new() .

票数 6
EN

Stack Overflow用户

发布于 2012-06-08 19:57:36

为什么不只是:

代码语言:javascript
复制
sub new {
    my $class = shift;
    my $self = $class->SUPER::new(@_);
    $self->do_some_additional_init();
    return $self;
};

-层次结构中最深的基类的唯一例外,它应该调用bless $self, $class;my $self = fields::new($class);,以防出现use fields

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10951292

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档