首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么继承自非Moo类的my Moo对象被祝福到父模块的包中呢?

为什么继承自非Moo类的my Moo对象被祝福到父模块的包中呢?
EN

Stack Overflow用户
提问于 2015-09-30 12:23:41
回答 2查看 626关注 0票数 8

我正试图使用Gtk3和Moo在Perl中创建一个Moo应用程序。有一个来自Gtk,Gtk::ApplicationWindow的非Moo类,我使用extends 'Gtk::ApplicationWindow'通过Moo子类。问题是,当创建该子类的对象时,它仍然是父类的类型--即Gtk::ApplicationWindow

我尝试了同样的方法,用子类代替我自己的非基于Moo的类,并且从这个子类创建的对象的类型是正确的。造成这种差异的原因是什么?

代码语言:javascript
复制
use v5.10;
use strict;
use warnings;

# Import the Gtk classes (non-Moo)
use Glib::Object::Introspection;
Glib::Object::Introspection->setup(basename => 'Gtk', version => '3.0', package => 'Gtk');
Glib::Object::Introspection->setup(basename => 'Gio', version => '2.0', package => 'Gio');

#################################################
{
    # A dummy non-Moo class
    package ClassNonMoo;
    sub new { bless {}, shift; }
}

{
    # Moo class extending the dummy class
    package ClassMoo;
    use Moo;

    extends 'ClassNonMoo';

    sub FOREIGNBUILDARGS {
        my ($class, %args) = @_;
        return ($args{app});
    }
}
#################################################

{
    # Moo class extending Gtk::ApplicationWindow
    package ClassMooGtkAppWin;
    use Moo;

    extends 'Gtk::ApplicationWindow';

    sub FOREIGNBUILDARGS {
        my ($class, %args) = @_;
        return ($args{app});
    }
}

#################################################

# Create objects of ClassMoo and ClassMooGtkAppWin
sub create_objects {
    my ($app) = @_;

    my $o1 = ClassMoo->new( app => $app );
    my $o2 = ClassMooGtkAppWin->new( app => $app );

    say "o1 = $o1\no2 = $o2";
    # Output:
    # o1 = ClassMoo=HASH(0x2f7bc50)
    # o2 = Gtk::ApplicationWindow=HASH(0x2f7bd40)
    #
    # Shouldn't o2 be of the type ClassMooGtkAppWin ?

    exit(0);
}

# We can create a GtkApplicationWindow only after creating a GtkApplication and
# running it. This code just ensures that create_object() is called once the
# application is 'active'.
my $app = Gtk::Application->new('org.test', 'flags-none');
$app->signal_connect(activate => sub { create_objects($app) });
$app->run();
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-30 19:33:21

“新”构造函数需要以某种方式编写,以观察调用者的实际类(它与子类一起工作),但它们也可以硬编码使用哪个类创建对象。

比较:

代码语言:javascript
复制
package MyClass;

# Considerate of subclassing
sub new {
    my $class = shift;
    return bless {}, $class;
}

# Doesn't give a shit
sub new {
    my $class = shift;
    return bless {};
}

Glib看起来像是一个围绕C库的XS模块包装器,它可能会对类进行硬编码。

您可能只需尝试将对象重新祝福(再次调用已构造的对象),将对象放入实际的子类中。不确定Moo会如何工作,但可能是在构建方法中。

您还可以跳过继承,转而使用委托。创建一个属性来保存原始窗口对象,然后将所有方法委托给它,子类中的方法除外。

在Moose (不是Moo)中,您可以使用regex:https://metacpan.org/pod/Moose#handles-ARRAY-HASH-REGEXP-ROLE-ROLETYPE-DUCKTYPE-CODE来完成这一任务。

不知道怎么用Moo做得更好。

票数 4
EN

Stack Overflow用户

发布于 2015-09-30 14:50:08

我找不到要验证的Gtk::ApplicationWindow,但很可能是这样

代码语言:javascript
复制
sub new {
   my ($class) = @_;
   return bless({});
}

而不是

代码语言:javascript
复制
sub new {
   my ($class) = @_;
   return bless({}, $class);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32866013

复制
相关文章

相似问题

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