Multiple Inheritance in Perl

November 5, 2024 ยท View on GitHub

Multiple Inheritance in Perl


Background

The general rule of thumb, Don't use multiple inheritance if you can do it in any other way.

If you still insist to do it, then let us explore the different options available. The default method resolution order is DFS i.e. depth first search. However there is a better alternative C3 where it uses breadth first search algorithm.

In the modern OOP i.e. Corinna, currently as in v5.40, there is no support for multiple inheritance.

Traditional Multiple Inheritance

#         CH
#       /    \
#      P1    P2
#       \    /
#         GP

package GP { 1;                                 }
package P1 { use parent -norequire, 'GP';       }
package P2 { use parent -norequire, 'GP';       }
package CH { use parent -norequire, 'P1', 'P2'; }

use v5.40;
use mro;

say "DFS: @{mro::get_linear_isa('CH')}";
say " C3: @{mro::get_linear_isa('CH', 'c3')}";

# DFS: CH, P1, GP, P2
#  C3: CH, P1, P2, GP

Moo Multiple Inheritance

#         CH
#       /    \
#      P1    P2
#       \    /
#         GP

package GP { use Moo;                     }
package P1 { use Moo; extends 'GP';       }
package P2 { use Moo; extends 'GP';       }
package CH { use Moo; extends 'P1', 'P2'; }

use v5.40;
use mro;

say "DFS: @{mro::get_linear_isa('CH')}";
say " C3: @{mro::get_linear_isa('CH', 'c3')}";

# DFS: CH, P1, GP, Moo::Object, P2
#  C3: CH, P1, P2, GP, Moo::Object

Example

use v5.40;

package GP {
    use Moo;
    sub hi  { say "Hi, GP."   }
    sub bye { say "Bye, GP."  }
}

package P1 {
    use Moo;
    extends 'GP';
}

package P2 {
    use Moo;
    extends 'GP';
    sub hi  { say "Hi, P2."  }
    sub bye { say "Bye, P2." }
}

package CH {
    use Moo;
    extends 'P1', 'P2';
    sub bye {
        shift->next::method(@_);
    }
}

use mro;

my $child = CH->new;

mro::set_mro('CH', 'dfs');
$child->hi;                # Hi, GP.
$child->bye;               # Bye, P2.

mro::set_mro('CH', 'c3');
$child->hi;                # Hi, P2.
$child->bye;               # Bye, P2.