在Moose中,我如何判断一个对象的类是否是另一个对象类的子类?

Rya*_*son 4 perl inheritance introspection moose

假设我有两个对象$obj1,$obj2它们都是Moose类的实例.我想找出以下哪项适用:

  • $obj1的班级与他们的班级相同$obj2;
  • $obj1的类是's的子类$obj2;
  • $obj1的班级是超级班级$obj2;
  • 对象的类都不是另一个的子类.

我怎样才能做到这一点?

Sin*_*nür 9

  1. $obj1我们的班级一样$obj2吗?

    ref $obj1 eq ref $obj2;
    
    Run Code Online (Sandbox Code Playgroud)
  2. $obj1这个类是's的子类$obj2吗?

    $obj1->isa(ref $obj2);
    
    Run Code Online (Sandbox Code Playgroud)
  3. $obj1班级的超级班$obj2吗?

    $obj2->isa(ref $obj1);
    
    Run Code Online (Sandbox Code Playgroud)
  4. 对象的类都不是另一个的子类.

    往上看.

更新:

回应有关在运行时应用的角色的评论:

package My::X;

use Moose; use namespace::autoclean;

sub boo { }

__PACKAGE__->meta->make_immutable;

package My::Y;

use Moose; use namespace::autoclean;

extends 'My::X';

__PACKAGE__->meta->make_immutable;

package My::Z;

use Moose::Role; use namespace::autoclean;

requires 'boo';

package main;

use Test::More tests => 2;

use Moose::Util qw( apply_all_roles );

my $x = My::X->new;
my $y = My::Y->new;

ok($y->isa(ref $x), 'Before role was applied at runtime');

apply_all_roles($x, 'My::Z');

ok($y->isa(ref $x), 'After role was applied at runtime');
Run Code Online (Sandbox Code Playgroud)

输出:

1..2
ok 1 - Before role was applied at runtime
not ok 2 - After role was applied at runtime
#   Failed test 'After role was applied at runtime' at C:\Temp\t.pl line 36.
# Looks like you failed 1 test of 2.

  • 在Moose中,您可以为单个对象添加角色或特征吗?如果你正在寻找相同的行为,这是这种想法出错的领域之一. (2认同)
  • @brian你可以,但它不会导致这些片段给出错误的答案,至少在纯粹的Liskov可替代性意义上(例如:如果Subclass继承自Base,$ a是Base + Role的一个实例(应用于$ a at运行时),$ b是Subclass的一个实例,它会说$ b的类不是$ a类的子类 - 但是在一个非常有用的意义上说这是真的.) (2认同)

dra*_*tun 5

使用您的Class::MOP基础Moose可以内省所有这些信息.

例如:

{
    package Daddy;
    use Moose;
}

{
    package Kid;
    use Moose;
    extends 'Daddy';
}

my $son      = Kid->new;
my $daughter = Kid->new;

my $sons_class                  = ($son->meta->class_precedence_list)[0];
my $daughters_class             = ($daughter->meta->class_precedence_list)[0];

my @sons_subclasses             = $son->meta->subclasses;     # or better...
my @daughters_subclasses        = $daughter->meta->direct_subclasses;

my @sons_superclasses           = $son->meta->superclasses;

my @Daddies_children            = Daddy->meta->direct_subclasses;
Run Code Online (Sandbox Code Playgroud)

另请参阅此SO问题/答案如何在Perl中找到从包中继承的所有包?

/ I3az /