Perl packages, bless, and inheritance
Create objects as blessed hashes, override methods in a subclass, and call the parent version.
On this page
Perl references and subroutines.
- Create objects as blessed hashes, override methods in a subclass, and call the parent version.
- Predict the sample output and explain the state changes.
- Complete the practice task and check the boundary cases.
The concept
Perl builds objects from ordinary data. A package is a namespace, and a class is a package whose subroutines are methods. bless attaches a package name to a reference, usually a hash, which makes it an object of that class. A method call $obj->method passes the object as the first argument, conventionally named $self.
Inheritance uses the parent pragma. -norequire tells it that the parent package is defined in the same file. A subclass can override a method and call the parent's version with SUPER::. isa tests whether an object belongs to a class or a subclass, can tests whether a method exists, and ref returns the class name. Method calls are resolved at run time, so the right version runs for each object.
Code example
use strict;
use warnings;
package Animal;
sub new {
my ($class, %args) = @_;
my $self = { name => $args{name} };
return bless $self, $class;
}
sub name { return $_[0]{name} }
sub sound { return 'generic noise' }
sub speak {
my $self = shift;
return $self->name . ' says ' . $self->sound;
}
package Dog;
use parent -norequire, 'Animal';
sub sound { return 'Woof' }
sub speak {
my $self = shift;
return $self->SUPER::speak() . '!';
}
package main;
my @animals = (Animal->new(name => 'Generic'), Dog->new(name => 'Rex'));
print $_->speak, "\n" for @animals;
print $animals[1]->isa('Animal') ? "a Dog is an Animal\n" : "not an Animal\n";
print Dog->can('speak') ? "Dog can speak\n" : "Dog cannot speak\n";
print ref($animals[1]), "\n";Generic says generic noise Rex says Woof! a Dog is an Animal Dog can speak Dog
Follow the code
Open the walkthrough to inspect the example one step at a time.
Show guided walkthrough
use strict;use warnings; package Animal; sub new { my ($class, %args) = @_; my $self = { name => $args{name} }; return bless $self, $class;} sub name { return $_[0]{name} }sub sound { return 'generic noise' } sub speak { my $self = shift; return $self->name . ' says ' . $self->sound;} package Dog;use parent -norequire, 'Animal'; sub sound { return 'Woof' } sub speak { my $self = shift; return $self->SUPER::speak() . '!';} package main; my @animals = (Animal->new(name => 'Generic'), Dog->new(name => 'Rex'));print $_->speak, "\n" for @animals;print $animals[1]->isa('Animal') ? "a Dog is an Animal\n" : "not an Animal\n";print Dog->can('speak') ? "Dog can speak\n" : "Dog cannot speak\n";print ref($animals[1]), "\n";Follow the example
Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.
View the complete dry-run table
| Step / line | What happens | State after step | Output so far |
|---|---|---|---|
| bless turns the plain hash into an object of the class that new was called on. | — | — | |
| Dog inherits from Animal. -norequire says the parent is in this file. | — | — | |
| Call the parent's speak and add an exclamation mark. | — | — | |
| The class name is passed to new as $class, so Dog->new creates a Dog. | — | — | |
| Each object runs its own class's speak. Animal::speak calls sound, which resolves to Dog::sound for the dog. | — | Generic says generic noise Rex says Woof! | |
| isa follows the inheritance chain. | — | Generic says generic noise Rex says Woof! a Dog is an Animal | |
| can checks that a method exists, including inherited ones. | — | Generic says generic noise Rex says Woof! a Dog is an Animal Dog can speak | |
| ref on a blessed reference returns the class name. | — | Generic says generic noise Rex says Woof! a Dog is an Animal Dog can speak Dog |
Behind the scenes
How Perl processes this code
Perl compiles the script internally before executing it. strict and warnings help identify mistakes.
Cost and common mistakes
Method dispatch is O(depth of the inheritance chain) per call, with caching.
- Object data in a plain hash is public by convention only. Modules such as Moo, Moose, and Object::Pad add stricter classes.
- Forgetting use strict in each file hides typos in method and variable names.
- If a subclass overrides new, it must call the parent's new through SUPER::new, or the parent's fields are not set.
Try it yourself
How would you add a Cat class?
Reveal answer and reasoning
Add package Cat; use parent -norequire, 'Animal'; sub sound { return 'Meow' }. The existing speak method works unchanged.