微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

perl – 为什么我的Moo对象继承自非Moo类,为某些模块添加到父包中?

我正在尝试使用 GObject IntrospectionMoo在Perl中创建一个Gtk3应用程序.有一个来自Gtk,Gtk :: applicationwindow的非Moo类,我使用extends’Gtk :: applicationwindow’通过Moo子类化.问题在于,当创建该子类的对象时,它仍然是父类的类型 – 即Gtk :: applicationwindow.

我通过继承自己的非基于Moo的类来尝试相同的事情,并且从这个子类创建的对象具有正确的类型.造成这种差异的原因是什么?

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();

解决方法

“new”构造函数需要以一种方式编写,以观察调用者的实际类(使用子类化),但它们也可以硬编码它们创建对象的类.

相比:

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,但可能在BUILD方法中.

您也可以跳过继承并使用委托.创建一个属性来保存原始的Window对象,然后将所有方法委托给它,除了你自己的子类.

在Moose(不是Moo)中,您可以使用正则表达式执行此操作:
https://metacpan.org/pod/Moose#handles-ARRAY-HASH-REGEXP-ROLE-ROLETYPE-DUCKTYPE-CODE

不知道如何与Moo很好地做到这一点.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(<>){ chomp; print "$_n" unless
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据进行拼凑,然后将拼凑后的数据用“|”连接在一起。表格内容如下: 员工号码员工姓名职位入职日期1001张三销售1980/12/17 0:00:
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,还不能保证书写一定正确。写了个Perl脚本,可快速构造MySQL脚本语句。脚本如下:#!/usr/bin/perluse strict;m
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了一个表的数据量统计日报,主要是针对数据库中使用较频繁,数据量又较大的31张表。该日报有两个sheet组成,第一个sheet是数据填写,第二个sh
在实际生产环境中,常常需要从后台日志中截取报文,报文的形式类似于.........一个后台日志有多个报文,每个报文可由操作流水唯一确定。以前用AWK写过一个,程序如下:beginline=`awk &
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让人领略到perl正则表达式的强大,程序如下:#!/usr/bin/perluse strict;my (%hash,%hash1,@arra
忍不住在 PerlChina 邮件列表中盘点了一下 Perl 里的 Web 应用框架(巧的是 PerlBuzz 最近也有一篇相关的讨论帖),于是乎,决定在我自己的 blog 上也贴一下 :) 原生 CGI/FastCGI 的 web app 对于较小的应用非常合适,但稍复杂一些就有些痛苦,但运行效率是最高的 ;) 如果是自己用 Perl 开发高性能的站,多推荐之。 Catalyst, CGI::A
bless有两个参数:对象的引用、类的名称。 类的名称是一个字符串,代表了类的类型信息,这是理解bless的关键。 所谓bless就是把 类型信息 赋予 实例变量。 程序包括5个文件: person.pm :实现了person类 dog.pm :实现了dog类 bless.pl : 正确的使用bless bless.wrong.pl : 错误的使用bless bless.cc : 使用C++语言实
gb2312转Utf的方法: use Encode; my $str = "中文"; $str_cnsoftware = encode("utf-8", decode("gb2312", $str));   Utf转 gb2312的方法: use Encode; my $str = "utf8中文"; $str_cnsoftware = encode("gb2312", decode("utf-8
  perl 计算硬盘利用率, 以%来查看硬盘资源是否存在IO消耗cpu资源情况; 部份代码参考了iostat源码;     #!/usr/bin/perl use Time::HiRes qw(gettimeofday); use POSIX; $SLEEPTIME=3; sub getDiskUtl() { $clock_ticks = POSIX::sysconf( &POSIX::_SC_