PERLOBJ(1)
β¨ PERLOBJ π perlobj β Perl object reference β¨
welcome to the manual page for perlobj, bestie. this is the Perl object reference, and yes it's long, but we're gonna get through it together. grab a strawberry π.
πΈ NAME πΈ
perlobj β Perl object reference π
π DESCRIPTION π
okay so this doc is the whole reference for Perl's object orientation features. If you're looking for an intro to object-oriented programming in Perl, bestie, that's a different page β go see perlootut. π
And before any of this makes sense, you gotta understand references in Perl first. That's perlreftut, go read it, it's giving essential. β¨
This document describes all of Perl's object-oriented (OO) features from the ground up. If you're just tryna write some OO code of your own, honestly you're probably better served by one of the object systems from CPAN that are described in perlootut. π«Ά
But if you're looking to write your own object system, or you need to maintain code that implements objects from scratch β then this is the doc for you, because it will help you understand exactly how Perl does object orientation. periodt. π
There are a few basic principles that define object oriented Perl:
- An object is simply a data structure that knows to which class it belongs. π¦
- A class is simply a package. A class provides methods that expect to operate on objects. π
- A method is simply a subroutine that expects a reference to an object (or a package name, for class methods) as the first argument. β
Let's look at each of these principles in depth. no cap, it's about to get good.
π§ An Object is Simply a Data Structure π§
Unlike so many other languages that support object orientation, Perl does not provide any special syntax for constructing an object. Nope! Objects are merely Perl data structures (hashes, arrays, scalars, filehandles, etc.) that have been explicitly associated with a particular class. that's the whole vibe. π
That explicit association is created by the built-in bless function, which is typically used inside the constructor subroutine of the class.
Here's a simple constructor:
package File;
sub new {
my $class = shift;
return bless {}, $class;
}
The name new isn't special. Not even a little. We could name our constructor something else entirely:
package File;
sub load {
my $class = shift;
return bless {}, $class;
}
The modern convention for OO modules is to always use new as the name for the constructor, but there is no requirement to do so. Any subroutine that blesses a data structure into a class is a valid constructor in Perl. slay. π₯
In the previous examples, the {} code creates a reference to an empty anonymous hash. The bless function then takes that reference and associates the hash with the class in $class. In the simplest case, the $class variable will end up containing the string File.
We can also use a variable to store a reference to the data structure that is being blessed as our object:
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
return $self;
}
Once we've blessed the hash referred to by $self we can start calling methods on it. This is useful if you want to put object initialization in its own separate method:
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$self->_initialize();
return $self;
}
Since the object is also a hash, you can treat it as one, using it to store data associated with the object. Typically, code inside the class can treat the hash as an accessible data structure, while code outside the class should always treat the object as opaque. This is called encapsulation. Encapsulation means that the user of an object does not have to know how it is implemented. The user simply calls documented methods on the object. main character energy, honestly. β¨
π Note, however, that (unlike most other OO languages) Perl does not ensure or enforce encapsulation in any way. If you want objects to actually be opaque you need to arrange for that yourself. This can be done in a variety of ways, including using Inside-Out objects or modules from CPAN. you're on your own for that one, bestie.
π Objects Are Blessed; Variables Are Not π
When we bless something, we are not blessing the variable which contains a reference to that thing, nor are we blessing the reference that the variable stores; we are blessing the thing that the variable refers to (sometimes known as the referent). This is best demonstrated with this code:
use Scalar::Util 'blessed';
my $foo = {};
my $bar = $foo;
bless $foo, 'Class';
print blessed( $bar ) // 'not blessed'; # prints "Class"
$bar = "some other value";
print blessed( $bar ) // 'not blessed'; # prints "not blessed"
When we call bless on a variable, we are actually blessing the underlying data structure that the variable refers to. We are not blessing the reference itself, nor the variable that contains that reference. That's why the second call to blessed( $bar ) returns false β at that point $bar is no longer storing a reference to an object. π
You will sometimes see older books or documentation mention "blessing a reference" or describe an object as a "blessed reference", but this is incorrect. It isn't the reference that is blessed as an object; it's the thing the reference refers to (i.e., the referent). periodt. π
π¦ A Class is Simply a Package π¦
Perl does not provide any special syntax for class definitions. A package is simply a namespace containing variables and subroutines. The only difference is that in a class, the subroutines may expect a reference to an object or the name of a class as the first argument. And honestly this is purely a matter of convention, so a class may contain both methods and subroutines which don't operate on an object or class. it's giving flexible. β¨
Each package contains a special array called @ISA. The @ISA array contains a list of that class's parent classes, if any. This array is examined when Perl does method resolution, which we will cover later. π
Calling methods from a package means it must be loaded, of course, so you will often want to load a module and add it to @ISA at the same time. You can do so in a single step using the parent pragma. (In older code you may encounter the base pragma, which is nowadays discouraged except when you have to work with the equally discouraged fields pragma.) πΈ
However the parent classes are set, the package's @ISA variable will contain a list of those parents. This is simply a list of scalars, each of which is a string that corresponds to a package name.
All classes inherit from the UNIVERSAL class implicitly. The UNIVERSAL class is implemented by the Perl core, and provides several default methods, such as isa(), can(), and VERSION(). The UNIVERSAL class will never appear in a package's @ISA variable. π«Ά
Perl only provides method inheritance as a built-in feature. Attribute inheritance is left up the class to implement. See the Writing Accessors section for details.
π A Method is Simply a Subroutine π
Perl does not provide any special syntax for defining a method. A method is simply a regular subroutine, and is declared with sub. What makes a method special is that it expects to receive either an object or a class name as its first argument. that's it, that's the whole secret. π
Perl does provide special syntax for method invocation, the -> operator. We will cover this in more detail later.
Most methods you write will expect to operate on objects:
sub save {
my $self = shift;
open my $fh, '>', $self->path() or die $!;
print {$fh} $self->data() or die $!;
close $fh or die $!;
}
π Method Invocation π
Calling a method on an object is written as $object->method.
The left hand side of the method invocation (or arrow) operator is the object (or class name), and the right hand side is the method name.
my $pod = File->new( 'perlobj.pod', $data );
$pod->save();
The -> syntax is also used when dereferencing a reference. It looks like the same operator, but these are two different operations. iykyk. π
When you call a method, the thing on the left side of the arrow is passed as the first argument to the method. That means when we call Critter->new(), the new() method receives the string Critter as its first argument. When we call $fred->speak(), the $fred variable is passed as the first argument to speak().
Just as with any Perl subroutine, all of the arguments passed in @_ are aliases to the original argument. This includes the object itself. If you assign directly to $_[0] you will change the contents of the variable that holds the reference to the object.
π We recommend that you don't do this unless you know exactly what you're doing. fr fr, don't.
Perl knows what package the method is in by looking at the left side of the arrow. If the left hand side is a package name, it looks for the method in that package. If the left hand side is an object, then Perl looks for the method in the package that the object has been blessed into.
If the left hand side is neither a package name nor an object, then the method call will cause an error, but see the section on Method Call Variations for more nuances. π
β Inheritance β
We already talked about the special @ISA array and the parent pragma. (iconic duo, honestly.)
When a class inherits from another class, any methods defined in the parent class are available to the child class. If you attempt to call a method on an object that isn't defined in its own class, Perl will also look for that method in any parent classes it may have.
package File::MP3;
use parent 'File'; # sets @File::MP3::ISA = ('File');
my $mp3 = File::MP3->new( 'Andvari.mp3', $data );
$mp3->save();
Since we didn't define a save() method in the File::MP3 class, Perl will look at the File::MP3 class's parent classes to find the save() method. If Perl cannot find a save() method anywhere in the inheritance hierarchy, it will die. π
In this case, it finds a save() method in the File class. Note that the object passed to save() in this case is still a File::MP3 object, even though the method is found in the File class. (the way that worksβ¦ obsessed.) β¨
We can override a parent's method in a child class. When we do so, we can still call the parent class's method with the SUPER pseudo-class.
sub save {
my $self = shift;
say 'Prepare to rock';
$self->SUPER::save();
}
The SUPER modifier can only be used for method calls. You can't use it for regular subroutine calls or class methods:
SUPER::save($thing); # FAIL: looks for save() sub in package SUPER
SUPER->save($thing); # FAIL: looks for save() method in class
# SUPER
$thing->SUPER::save(); # Okay: looks for save() method in parent
# classes
π How SUPER is Resolved π
(to be continued, bestie β this part is still loading β¨)
Okay so the SUPER pseudo-class? π
It gets resolved from the package where the call is made. Not from the object's class. And bestie, that is so important, because it's literally what lets methods at different levels of a deep inheritance hierarchy each correctly call their own respective parent methods. π«Ά
package A;
sub new {
return bless {}, shift;
}
sub speak {
my $self = shift;
say 'A';
}
package B;
use parent -norequire, 'A';
sub speak {
my $self = shift;
$self->SUPER::speak();
say 'B';
}
package C;
use parent -norequire, 'B';
sub speak {
my $self = shift;
$self->SUPER::speak();
say 'C';
}
my $c = C->new();
$c->speak();
And in this example we get this output, no cap:
A
B
C
So this is the whole demonstration of how SUPER resolves. β¨ Even though the object is blessed into the C class, the speak() method in the B class can still call SUPER::speak() and expect it to correctly look in the parent class of B (aka the class the method call is in), not in the parent class of C (aka the class the object actually belongs to). π
There are rare cases where this package-based resolution can be a problem, though. π If you copy a subroutine from one package to another, SUPER resolution will be done based on the original package. That's the gotcha. Remember it.
π¦ Multiple Inheritance π¦
Multiple inheritance often indicates a design problem, but Perl always gives you enough rope to hang yourself with if you ask for it. π That's just the deal, bestie.
To declare multiple parents, you simply need to pass multiple class names to use parent:
package MultiChild;
use parent 'Parent1', 'Parent2';
πΈ Method Resolution Order πΈ
Method resolution order only matters in the case of multiple inheritance, fr fr. In the case of single inheritance, Perl just looks up the inheritance chain to find a method:
Grandparent
|
Parent
|
Child
So if we call a method on a Child object and that method is not defined in the Child class, Perl will look for that method in the Parent class and then, if necessary, in the Grandparent class. π
And if Perl cannot find the method in any of these classes? It will die with an error message. π
When a class has multiple parents, the method lookup order becomes more complicated. π
By default, Perl does a depth-first left-to-right search for a method. That means it starts with the first parent in the @ISA array, and then searches all of its parents, grandparents, etc. If it fails to find the method, it then goes to the next parent in the original class's @ISA array and searches from there.
SharedGreatGrandParent
/ \
PaternalGrandparent MaternalGrandparent
\ /
Father Mother
\ /
Child
So given the diagram above, Perl will search Child, Father, PaternalGrandparent, SharedGreatGrandParent, Mother, and finally MaternalGrandparent. π And this may be a problem, because now we're looking in SharedGreatGrandParent before we've checked all its derived classes β like, before we tried Mother and MaternalGrandparent. Rude.
It is possible to ask for a different method resolution order with the mro pragma. β¨
package Child;
use mro 'c3';
use parent 'Father', 'Mother';
This pragma lets you switch to the C3 resolution order. In simple terms, C3 order ensures that shared parent classes are never searched before child classes, so Perl will now search: Child, Father, PaternalGrandparent, Mother, MaternalGrandparent, and finally SharedGreatGrandParent. π
But heads up: this is not "breadth-first" searching. All theFatherancestors (except the common ancestor) are searched before any of theMotherancestors are considered. Don't get it twisted.
The C3 order also lets you call methods in sibling classes with the next pseudo-class. π See the mro documentation for more details on this feature.
π Method Resolution Caching π
When Perl searches for a method, it caches the lookup so that future calls to the method do not need to search for it again. π§ Changing a class's parent class or adding subroutines to a class will invalidate the cache for that class.
And the mro pragma provides some functions for manipulating the method cache directly, iykyk. β¨
π Writing Constructors π
As we mentioned earlier, Perl provides no special constructor syntax. π Which means a class must implement its own constructor. A constructor is simply a class method that returns a reference to a new object. That's it, that's the whole vibe.
The constructor can also accept additional parameters that define the object. Let's write a real constructor for the File class we used earlier:
package File;
sub new {
my $class = shift;
my ( $path, $data ) = @_;
my $self = bless {
path => $path,
data => $data,
}, $class;
return $self;
}
So as you can see, we've stored the path and file data in the object itself. π Remember: under the hood, this object is still just a hash. Later, we'll write accessors to manipulate this data.
For our File::MP3 class, we can check to make sure that the path we're given ends with .mp3:
package File::MP3;
sub new {
my $class = shift;
my ( $path, $data ) = @_;
die "You cannot create a File::MP3 without an mp3 extension\n"
unless $path =~ /\.mp3\z/;
return $class->SUPER::new(@_);
}
This constructor lets its parent class do the actual object construction. π«Ά Delegation, slay.
π Attributes π
An attribute is a piece of data belonging to a particular object. Unlike most object-oriented languages, Perl provides no special syntax or support for declaring and manipulating attributes. π
Attributes are often stored in the object itself. For example, if the object is an anonymous hash, we can store the attribute values in the hash using the attribute name as the key.
While it's possible to refer directly to these hash keys outside of the class, it's considered a best practice to wrap all access to the attribute with accessor methods. πΈ
This has several advantages, bestie:
- Accessors make it easier to change the implementation of an object later while still preserving the original API. β¨
- An accessor lets you add additional code around attribute access. Like, you could apply a default to an attribute that wasn't set in the constructor, or you could validate that a new value for the attribute is acceptable. π
- Finally, using accessors makes inheritance much simpler. Subclasses can use the accessors rather than having to know how a parent class is implemented internally. π«Ά
π Writing Accessors π
As with constructors, Perl provides no special accessor declaration syntax, so classes must provide explicitly written accessor methods. There are two common types of accessors: read-only and read-write. π
A simple read-only accessor simply gets the value of a single attribute:
sub path {
my $self = shift;
return $self->{path};
}
A read-write accessor will allow the caller to set the value as well as get it:
sub path {
my $self = shift;
if (@_) {
$self->{path} = shift;
}
return $self->{path};
}
β An Aside About Smarter and Safer Code β
Our constructor and accessors are not very smart. π They don't check that a $path is defined, nor do they check that a $path is a valid filesystem path. π
And doing these checks by hand can quickly become tedious. Writing a bunch of accessors by hand is also incredibly tedious. Not the vibe.
But! There are a lot of modules on CPAN that can help you write safer and more concise code, including the modules we recommend in perlootut. π¦ Go look, bestie.
π Method Call Variations π
Perl supports several other ways to call methods besides the $object->method() usage we've seen so far. Let's get into it. β¨
π Method Names with a Fully Qualified Name π
Perl allows you to call methods using their fully qualified name (the package and method name):
my $mp3 = File::MP3->new( 'Regin.mp3', $data );
$mp3->File::save();
When you call a fully qualified method name like File::save, the method resolution search for the save method starts in the File class, skipping any save method the File::MP3 class may have defined. It still searches the File class's parents if necessary. π
While this feature is most commonly used to explicitly call methods inherited from an ancestor class, there is no technical restriction that enforces this:
my $obj = Tree->new();
$obj->Dog::bark();
This calls the bark method from class Dog on an object of class Tree, even if the two classes are completely unrelated. π
Use this with great care. Seriously. It will not save you.
And btw, the SUPER pseudo-class that was described earlier is not the same as calling a method with a fully-qualified name. See the earlier "Inheritance" section for details. π
πΈ Method Names as Strings πΈ
Perl lets you use a scalar variable containing a string as a method name:
my $file = File->new( $path, $data );
my $method = 'save';
$file->$method();
This works exactly like calling $file->save(). π«Ά This can be very useful for writing dynamic code. For example, it allows you to pass a method name to be called as a parameter to another method. Iconic, honestly.
π¦ Class Names as Strings π¦
Perl also lets you use a scalar containing a string as a class name:
my $class = 'File';
my $file = $class->new( $path, $data );
Again, this allows for very dynamic code. β¨
π Subroutine References as Methods π
You can also use a subroutine reference as a method:
my $sub = sub {
my $self = shift;
$self->save();
};
$file->$sub();
This is exactly equivalent to writing $sub->($file). π
You may see this idiom in the wild combined with a call to can:
if ( my $meth = $object->can('foo') ) {
$object->$meth();
}
π Dereferencing Method Call π
Perl also lets you use a dereferenced scalar reference in a method call. That's a mouthful, so let's look at some code:
$file->${ \'save' };
$file->${ returns_scalar_ref() };
$file->${ \( returns_scalar() ) };
$file->${ returns_ref_to_sub_ref() };
This works if the dereference produces a string or a subroutine reference. π
π§ Method Calls on Filehandles π§
Under the hood, Perl filehandles are instances of the IO::Handle or IO::File class. π Once you have an open filehandle, you can call methods on it. And bonus: you can also call methods on the STDIN, STDOUT, and STDERR filehandles. β¨
open my $fh, '>', 'path/to/file';
$fh->autoflush();
$fh->print('content');
STDOUT->autoflush();
β¨ Invoking Class Methods β¨
ok so real talk: Perl lets you use barewords for package names AND subroutine names, and sometimes it just... guesses wrong?? like it picks the wrong meaning of your bareword and you're left standing there like π.
Exhibit A: the construct Class->new(). Perl can read that two ways:
'Class'->new()β a method call on the class literally namedClassClass()->new()β call a subroutine namedClass(), THEN callnew()as a method on whateverClass()handed back
In English bestie, that second one is "call a sub called Class(), then call new() on the return value." And here's the tea: if a subroutine named Class() exists in the current namespace, Perl will always go with interpretation #2. Every single time. No discussion. π«
So how do you force interpretation #1 (method call on the class named Class)? Two ways, pick your fighter:
First β just slap a :: on the end of the class name:
Class::->new()
Perl will always read that as a method call. Iconic. π
Alternatively, quote the class name:
'Class'->new()
And obviously if your class name lives in a scalar, Perl does the right thing all on its own:
my $class = 'Class';
$class->new();
π¦ Indirect Object Syntax π¦
Outside of the file handle case, use of this syntax is discouraged as it can confuse the Perl interpreter. See below for more details.
So Perl supports another method invocation syntax called "indirect object" notation. It's called "indirect" because the method comes before the object it's being invoked on. Backwards, lowkey.
It works with any class or object method:
my $file = new File $path, $data;
save $file;
But bestie... we recommend you avoid this syntax, and here's why:
Reason 1 β it's a mess to read. In that example above, is save a method the File class provides? Or is it just some subroutine that happens to expect a file object as its first argument? Nobody knows. Not even you. π
Reason 2 β with class methods it gets worse. Because Perl allows subroutine names as barewords, Perl has to guess whether the bareword after the method is a class name or a subroutine name. So it could resolve as either File->new( $path, $data ) or new( File( $path, $data ) ). Two completely different programs!
To parse this, Perl uses a heuristic based on what package names it's seen, what subroutines exist in the current package, what barewords it saw earlier, and other input. And heuristics, bestie? Heuristics can produce VERY surprising results. π
Older documentation (and some CPAN modules) actively encouraged this syntax, especially for constructors, so you may still run into it in the wild. But for new code β please don't. We're begging.
You can force Perl to read the bareword as a class name by appending :: to it, same as before:
my $file = new File:: $path, $data;
Indirect object syntax is only available when the indirect named feature is enabled. It's enabled by default, but you can disable it if you ask nicely. It's present in older feature version bundles, but it was removed from the :5.36 bundle β so a use VERSION declaration of v5.36 or above will also disable the feature:
use v5.36;
# indirect object syntax is no longer available
π "bless", "blessed", and "ref" π
So like we said earlier, an object is just a data structure that's been blessed into a class via the bless function. And bless takes either one or two arguments:
my $object = bless {}, $class;
my $object = bless {};
Form one: that anonymous hash gets blessed into the class held in $class. Form two: the anonymous hash gets blessed into the current package.
Form two is strongly discouraged β it breaks a subclass's ability to reuse the parent's constructor. But you'll still see it in existing code, so know it when you see it. π
Now β wanna know if a particular scalar refers to an object? Use the blessed function, exported by Scalar::Util, which ships with the Perl core:
use Scalar::Util 'blessed';
if ( defined blessed($thing) ) { ... }
If $thing refers to an object, this returns the name of the package that object was blessed into. If $thing isn't a reference to a blessed object, blessed returns undef.
Sneaky little gotcha: blessed($thing) will also return false if $thing was blessed into a class named "0". Yeah, that's possible. It's also pretty pathological. Don't make a class named "0" unless you genuinely know what you're doing. π«
Similarly, Perl's built-in ref function treats a blessed object reference specially β call ref($thing) and if $thing holds an object reference, it returns the name of the class the object was blessed into.
If all you want is "does this variable hold an object reference", we recommend defined blessed($object) β because ref returns true values for all references, not just objects. Big difference, no cap.
π The UNIVERSAL Class π
Every class automatically inherits from the UNIVERSAL class, which is built right into the Perl core. It provides a bunch of methods, and all of them can be called on either a class or an object. You can also override some of these in your own class β and if you do, we recommend you follow the built-in semantics described below. β¨
isa($class)β returns true if the object is a member of the class in$class, or a member of a subclass of$class. If you override this method, it should never throw an exception.DOES($role)β returns true if its object claims to perform the role$role. By default this is equivalent toisa. It's provided for object system extensions that implement roles, likeMooseandRole::Tiny. You can also overrideDOESdirectly in your own classes. If you override this method, it should never throw an exception.can($method)β checks whether the class or object it was called on has a method named$method. It checks the class and all of its parents. If the method exists, you get a reference to the subroutine back. If it doesn't, you getundef. If your class responds to method calls viaAUTOLOAD, you may want to overloadcanto return a subroutine reference for the methods yourAUTOLOADhandles. If you override this method, it should never throw an exception.VERSION($need)β returns the version number of the class (package). If the$needargument is given, it checks that the current version (as defined by the$VERSIONvariable in the package) is greater than or equal to$needβ and it will die if that's not the case. This method is called automatically by theVERSIONform ofuse:
use Package 1.2 qw(some imported subs);
# implies:
Package->VERSION(1.2);
We recommend using this method to grab another package's version instead of looking directly at $Package::VERSION β because the package you're peeking at could have overridden the VERSION method. Rude of them, but legal. π
We also recommend using this method to check whether a module has a sufficient version. The internal implementation uses the version module to make sure different types of version numbers get compared correctly.
πΈ AUTOLOAD πΈ
If you call a method that doesn't exist in a class, Perl throws an error. BUT β if that class, or any of its parent classes, defines an AUTOLOAD method, then that AUTOLOAD method gets called instead. Catch-all behaviour, activated. πͺ
AUTOLOAD is called as a regular method, and the caller will never know the difference. Whatever value your AUTOLOAD returns is what gets returned to the caller.
The fully qualified method name that was called is available in the $AUTOLOAD package global for your class. And since it's a global, if you want to refer to it without a package name prefix under strict 'vars', you have to declare it. Periodt.
# XXX - this is a terrible way to implement accessors, but it makes
# for a simple example.
our $AUTOLOAD;
sub AUTOLOAD {
my $self = shift;
# Remove qualifier from original method name...
my $called = $AUTOLOAD =~ s/.*:://r;
# Is there an attribute of that name?
die "No such attribute: $called"
unless exists $self->{$called};
# If so, return it...
return $self->{$called};
}
sub DESTROY { } # see below
Without that our $AUTOLOAD declaration, this code will not compile under the strict pragma. Ask us how we know. π
And like the comment says β this is not a good way to implement accessors. It's slow and too clever by half. But you may see it used to provide accessors in older Perl code, so now you'll recognise it. For actual recommendations on OO coding in Perl, go read perlootut.
If your class does have anAUTOLOADmethod, we strongly recommend you overridecanin your class as well. Your overriddencanshould return a subroutine reference for any method yourAUTOLOADresponds to.
π Destructors π
When the last reference to an object goes away, the object is destroyed. If you've only got one reference to an object sitting in a lexical scalar, the object dies when that scalar goes out of scope. But if you store the object in a package global, that object might not go out of scope until the program exits. So... plan accordingly. π«Ά
Wanna do something when the object is destroyed? Define a DESTROY method in your class. Perl will always call this method at the appropriate time β unless the method is empty.
It's called just like any other method, with the object as the first argument. It doesn't receive any additional arguments. However, $_[0] will be read-only inside the destructor, so you cannot assign a value to it. Hands off. π
If your DESTROY method throws an exception, that will not cause any control transfer beyond exiting the method. The exception gets reported to STDERR as a warning, marked (in cleanup), and Perl just carries on with whatever it was doing before. Resilient queen.
BecauseDESTROYmethods can be called at any time, you should localize any global status variables that might get set by anything you do in yourDESTROYmethod. If you're in doubt about a particular status variable, it doesn't hurt to localize it. There are five global status variables, and the safest move is to localize all five of them:
sub DESTROY {
local($., $@, $!, $^E, $?);
my $self = shift;
...;
}
Okay so here's the tea: if you define an AUTOLOAD in your class, then Perl will call your AUTOLOAD to handle the DESTROY method too. Like, it just will. π You can stop that from happening by defining an empty DESTROY, exactly like we did back in the autoloading example. Or β equally valid β you can peek at the value of $AUTOLOAD and just return without doing anything when you get called to handle DESTROY. Either way works bestie π
πΈ Global Destruction πΈ
Okay this one's a little chaotic, so lock in. The order in which objects are destroyed during the global destruction before the program exits is unpredictable. π Which means any objects contained by your object may <em>already</em> have been destroyed by the time you get there. So pls pls pls check that a contained object is actually defined before you call a method on it:
sub DESTROY {
my $self = shift;
$self->{handle}->close() if $self->{handle};
}
See that if $self->{handle}? That's the vibe check. π«Ά
You can also use the ${^GLOBAL_PHASE} variable to detect if you're currently in the global destruction phase:
sub DESTROY {
my $self = shift;
return if ${^GLOBAL_PHASE} eq 'DESTRUCT';
$self->{handle}->close();
}
Important note: this variable was added in Perl 5.14.0. If you want to detect the global destruction phase on older versions of Perl, you can use the Devel::GlobalDestruction module on CPAN. β¨
Also, if your DESTROY method issues a warning during global destruction, the Perl interpreter will append the string during global destruction to the warning. So if you see that phrase chilling at the end of a warning, now you know why. π
And during global destruction, Perl will always garbage collect objects <em>before</em> unblessed references. See "PERL_DESTRUCT_LEVEL" in perlhacktips for more info about global destruction. iykyk π
π¦ Non-Hash Objects π¦
So every example so far has been a blessed hash, right? Plot twist: it's possible to bless any type of data structure or referent, including scalars, globs, and subroutines. So when you're out in the wild reading other people's code and see something feral, don't panic. π§
Here's an example of a module as a <em>blessed scalar</em>:
package Time;
use v5.36;
sub new {
my $class = shift;
my $time = time;
return bless \$time, $class;
}
sub epoch {
my $self = shift;
return $$self;
}
my $time = Time->new();
print $time->epoch();
See how it's all \$time and $$self? Iconic. π
π Inside-Out objects π
History lesson time bestie. In the past, the Perl community experimented with a technique called "inside-out objects". An inside-out object stores its data <em>outside</em> of the object's reference, indexed on a unique property of the object β like its memory address β rather than in the object itself. The whole point? It has the advantage of enforcing the encapsulation of object attributes, since their data is not stored in the object itself. π₯
This technique was popular for a while (and was actually recommended in Damian Conway's Perl Best Practices), but it never achieved universal adoption. The Object::InsideOut module on CPAN provides a comprehensive implementation of this technique, and you may see it or other inside-out modules in the wild. π
Here's a simple example of the technique, using the Hash::Util::FieldHash core module. This module was added to the core <em>specifically</em> to support inside-out object implementations:
package Time;
use v5.36;
use Hash::Util::FieldHash 'fieldhash';
fieldhash my %time_for;
sub new {
my $class = shift;
my $self = bless \( my $object ), $class;
$time_for{$self} = time;
return $self;
}
sub epoch {
my $self = shift;
return $time_for{$self};
}
my $time = Time->new;
print $time->epoch;
Look at that fieldhash my %time_for β the data lives in the hash, not the object. Main character energy honestly. β¨
π Pseudo-hashes π
RIP to a real one, the pseudo-hash feature was an experimental feature introduced in earlier versions of Perl and removed in 5.10.0. A pseudo-hash is an array reference which can be accessed using named keys like a hash. So yeah, you may run into some code in the wild which uses it. See the fields pragma for more information. π―οΈ
π SEE ALSO π
- perlootut β a kinder, gentler tutorial on object-oriented programming in Perl. Start here if you want the soft launch. πΌ
- perlmodlib β check this out for some style guides on constructing both modules and classes. π
And that's a wrap on the whole page, bestie!! π You just read perl v5.42.3, dated 2026-08-03, and honestly? Slay. Go bless something. π«Άβ¨π
π¦ where this page comes from
- fedora 43: perl-doc 5.42.3-524.fc43 Β· (GPL-1.0-or-later OR Artistic-1.0-Perl) AND Unicode-3.0 AND LicenseRef-Fedora-UltraPermissive
- fedora 44: perl-doc 5.42.3-525.fc44 Β· (GPL-1.0-or-later OR Artistic-1.0-Perl) AND Unicode-3.0 AND LicenseRef-Fedora-UltraPermissive
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms