History of the issue:
From the first release of Perl 5, the language has supported a basic object model through the mechanism of linking references with packages (blessing). In Perl, objects are ordinary references (to hash, array, or scalar) that are "blessed" by the bless function, which allows the system to find methods through the package (namespace).
Problem:
Unblessed references remain regular data structures, and attempting to call a method on them results in runtime errors. A programmer, without proper attention to the reference type, risks accidentally manipulating the internals of the object, violating encapsulation. Also, working with "raw" dereferencing operations {} or @{} without checks leads to hard-to-catch bugs.
Solution:
Correctly create objects only through bless, then access the object's data only through dereferencing, checking the type using the Scalar::Util module (ref, blessed). It is always advisable to avoid direct access to structures (e.g., $obj->{key}) outside of class methods and implement accessors (getter/setter) for control.
Code example:
package Animal; sub new { my $class = shift; my $self = { name => shift }; bless $self, $class; return $self; } sub name { my $self = shift; $self->{name} = shift if @_; return $self->{name}; } my $dog = Animal->new("Rex"); print $dog->name; # safely through accessor print $dog->{name}; # direct access, not recommended
Key features:
blessed or ref significantly reduce the number of bugsCan a regular hash reference be used as an object without bless?
No, without invoking bless, the reference has no association with the package, and Perl will not find the methods (there will be a "Can't call method" error), despite having an identical internal structure.
How to safely determine if a variable is really an object, not just a reference?
Use the Scalar::Util::blessed($obj) function to check if the reference is blessed. Only blessed references are considered objects.
use Scalar::Util 'blessed'; my $obj = {}; print blessed($obj) ? 'yes' : 'no'; # will output 'no'
Can a method be called on a non-object reference without errors?
Calling a method on an unblessed reference will result in a fatal error: Perl expects the reference to know about its package. Exceptions include AUTOLOAD mechanisms and dynamic loading, but this is an anti-pattern that leads to errors.
A young developer manually creates a structure $person = {name => 'Vasya'} and forgets to call bless, then tries to call $person->name(), which leads to a runtime error.
Advantages:
Disadvantages:
In the code, bless is always called when creating an object, and only the method name() is used to access the data. Checking via blessed() allows handling errors before executing methods.
Advantages:
Disadvantages: