Inheritance in Perl is implemented using the @ISA array, which specifies the packages (classes) from which the current package inherits. This is not traditional OO, as in many other languages, but rather a dynamic substitution of parents at the time of method lookup.
In early versions of Perl, there was no standard object-oriented approach. To support inheritance, the @ISA array (ISA = Is A) was introduced, which lists parent classes. Perl looks for methods first in the class of the object itself, and then in order in the parents, providing certain flexibility but also generating its own quirks.
Methods of inheritance via @ISA can easily break encapsulation. Furthermore, multiple inheritance requires careful handling of the order of parents to avoid unexpected method conflicts. An important point becomes the Method Resolution Order, which is not always obvious, especially when using CPAN modules (for example, classes from Moose, base, or parent).
For simple inheritance in Perl, an @ISA array is declared:
package Parent; sub hello { print "Hello from parent! "; } package Child; our @ISA = ('Parent'); Child::hello(); # Outputs: Hello from parent!
In real projects, the base or parent pragma is often used to simplify working with inheritance and enhance safety.
@ISA array.Can BASE-pragma or using the @ISA array add parent methods to the child class after the program starts?
No, Perl allows inheritance during script compilation, not during execution. If changes to @ISA occur during execution, they will not affect all already declared objects, which can lead to strange issues.
package Parent; sub hello { print "parent "; } package Child; our @ISA = ('Parent'); # it's not recommended to change @ISA after object creation
What happens if the same method is declared in several parent classes in @ISA?
The first found in the order specified in @ISA will be called. This can lead to unexpected behavior, especially in multiple inheritance.
package Base1; sub hello { print "Base1 "; } package Base2; sub hello { print "Base2 "; } package Derived; our @ISA = ('Base1', 'Base2'); Derived::hello(); # Outputs: Base1
Is it possible to dynamically add a class to @ISA and access its methods?
Yes, it is possible, but it is highly discouraged, as it breaks the program structure and can lead to method resolution errors and runtime errors.
@ISA during program executionparent/base pragmas, which reduces maintainabilityIn a project, to add functionality to protocol classes, the @ISA array is manually changed in a loop to inherit methods from dynamically loaded modules based on conditions.
Pros:
Cons:
To extend a class, the parent pragma is used, strictly controlling the order of parents and explicitly defining methods that can be overridden.
Pros:
Cons: