Classic OOP with bless

27.1 The Three Rules of Perl OOP

A class is a package.

A method is a subroutine that receives the object (or class name) as its first argument.

An object is a reference blessed into a package.

package Person;
use v5.36;
use Carp qw(croak);

sub new($class, %args) {
    croak 'name is required' unless defined $args{name};
    my $self = {
        name => $args{name},
        age  => $args{age} // 0,
        _friends => [],
    };
    return bless $self, $class;          # associate the hashref with the class
}

# Accessors
sub name($self) { $self->{name} }
sub age($self, @new) {                   # combined getter/setter
    $self->{age} = $new[0] if @new;
    return $self->{age};
}

sub add_friend($self, $friend) { push $self->{_friends}->@*, $friend; return $self }   # chainable
sub friends($self) { $self->{_friends}->@* }
sub greet($self) { sprintf "Hi, I'm %s (%d)", $self->name, $self->age }
sub to_string($self) { $self->greet }

package main;
my $ana = Person->new(name => 'Ana', age => 30);    # class method call
my $bo  = Person->new(name => 'Bo');
$ana->add_friend($bo)->age(31);
say $ana->greet;
say ref $ana;                         # Person
my $method = 'greet';
say $ana->$method();                  # dynamic method name
my $class = 'Person';
my $cy = $class->new(name => 'Cy');   # dynamic class name

27.2 Encapsulation Options

Hash-based objects (the most common; "private" by convention with _).

Inside-out objects (data stored in lexical hashes keyed by refaddr, e.g., Hash::Util::FieldHash): true privacy, rarely used now.

Closures as objects (behavior captured in subs).

Array-based objects (faster, less flexible).

The core class feature (Module 30) gives truly private fields.

27.3 Class Data and Destructors

package Connection;
my $instances = 0;                    # class data via a file-scoped lexical
sub new($class) { $instances++; bless {}, $class }
sub count($class) { $instances }
sub DESTROY($self) { $instances--; }  # called when the last reference goes away