为什么我的从非 Moo class 继承的 Moo 对象被祝福到某些模块的父包中?
Why is my Moo object that inherits from a non-Moo class blessed into the parent's package for some modules?
我正在尝试使用 GObject Introspection and Moo 在 Perl 中创建 Gtk3 应用程序。有一个来自 Gtk 的非 Moo class,Gtk::ApplicationWindow
,我使用 extends 'Gtk::ApplicationWindow'
通过 Moo 子class。问题是,当创建该子 class 的对象时,它仍然是父 class 的类型 - 即 Gtk::ApplicationWindow
.
我通过 subclass 我自己的非基于 Moo 的 class 尝试了同样的事情,并且从这个 subclass 创建的对象是正确的类型。造成这种差异的原因可能是什么?
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();
我找不到 Gtk::ApplicationWindow 来验证,但它可能
sub new {
my ($class) = @_;
return bless({});
}
而不是
sub new {
my ($class) = @_;
return bless({}, $class);
}
"new" 构造函数需要以观察调用者实际 class(与 subclassing 一起使用)的方式编写,但它们也可以硬编码哪个 class 他们用.
创建对象
比较:
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 模块包装器,它可能对 class.
进行硬编码
您可能只是尝试将对象重新祝福(对构建的对象再次调用祝福)到您的实际子对象中class。不确定这将如何与 Moo 一起工作,但可能在 BUILD 方法中。
您也可以跳过继承而改用委派。创建一个属性来保存原始 Window 对象,然后将 所有 方法委托给它,除了你自己在 subclass.
中
在 Moose(不是 Moo)中,您可以使用正则表达式执行此操作:
https://metacpan.org/pod/Moose#handles-ARRAY-HASH-REGEXP-ROLE-ROLETYPE-DUCKTYPE-CODE
不确定如何使用 Moo 很好地做到这一点。
我正在尝试使用 GObject Introspection and Moo 在 Perl 中创建 Gtk3 应用程序。有一个来自 Gtk 的非 Moo class,Gtk::ApplicationWindow
,我使用 extends 'Gtk::ApplicationWindow'
通过 Moo 子class。问题是,当创建该子 class 的对象时,它仍然是父 class 的类型 - 即 Gtk::ApplicationWindow
.
我通过 subclass 我自己的非基于 Moo 的 class 尝试了同样的事情,并且从这个 subclass 创建的对象是正确的类型。造成这种差异的原因可能是什么?
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();
我找不到 Gtk::ApplicationWindow 来验证,但它可能
sub new {
my ($class) = @_;
return bless({});
}
而不是
sub new {
my ($class) = @_;
return bless({}, $class);
}
"new" 构造函数需要以观察调用者实际 class(与 subclassing 一起使用)的方式编写,但它们也可以硬编码哪个 class 他们用.
创建对象比较:
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 模块包装器,它可能对 class.
进行硬编码您可能只是尝试将对象重新祝福(对构建的对象再次调用祝福)到您的实际子对象中class。不确定这将如何与 Moo 一起工作,但可能在 BUILD 方法中。
您也可以跳过继承而改用委派。创建一个属性来保存原始 Window 对象,然后将 所有 方法委托给它,除了你自己在 subclass.
中在 Moose(不是 Moo)中,您可以使用正则表达式执行此操作: https://metacpan.org/pod/Moose#handles-ARRAY-HASH-REGEXP-ROLE-ROLETYPE-DUCKTYPE-CODE
不确定如何使用 Moo 很好地做到这一点。