Search code examples
perlinheritanceintrospectionmoose

In Moose, how can I tell whether one object's class is a subclass of another object's class?


Suppose I have two objects $obj1 and $obj2 that are both instances of Moose classes. I want to find out which of the following applies:

  • $obj1's class is the same as $obj2's;
  • $obj1's class is a subclass of $obj2's;
  • $obj1's class is a superclass of $obj2's;
  • Neither object's class is a subclass of the other's.

How can I do this?


Solution

    1. Is $obj1's class the same as $obj2's?

      ref $obj1 eq ref $obj2;
      
    2. Is $obj1's class a subclass of $obj2's?

      $obj1->isa(ref $obj2);
      
    3. Is $obj1's class a superclass of $obj2's?

      $obj2->isa(ref $obj1);
      
    4. Neither object's class is a subclass of the other's.

      See above.

    Update:

    In response to comments regarding roles applied at run time:

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

    Output:

    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.