For the part of the software intended for educational purposes, this is illogical. Most of the ambiguity is the methods after new . Something like
sub name { &{ $_[0] }("NAME", @_[ 1 .. $#_ ] ) }
opaque and not needed. Modern equivalent
sub name { my $self = shift; $self->('NAME', @_); }
It also discusses whether $self should be a hash link, as it is, or a link to a blissful subroutine in which I believe it should be.
If I rename the hash link $data (it does not have a name at all, except for the closure code) and the $self subroutine, then maybe you will see something more recognizable? I also added a suitable boiler and some extra space.
person.pm
use strict; use warnings; package Person; sub new { my $class = shift; $class = ref($class) || $class; my $data = { NAME => undef, AGE => undef, PEERS => [], }; my $self = sub { my $fname = shift; my $field = $data->{$fname}; $data->{$fname} = shift if @_; return $field; }; return bless $self, $class; } sub name { my $self = shift; $self->('NAME', @_); } sub age { my $self = shift; $self->('AGE', @_); } sub peers { my $self = shift; $self->('PEERS', @_); } 1;
program.pl
use strict; use warnings; use Person; my $person = Person->new; $person->name('Jason'); $person->age(23); $person->peers([qw/ Norbert Rhys Phineas /]); printf "%s is %d years old.\n", $person->name, $person->age; my $peers = $person->peers; print "His peers are: ", join(", ", @$peers), "\n";
I hope this is clearer. You can bless only a scalar link, but while this is usually a hash link, here it is a closure link that is part of the code along with the data that it had access to at the time it was closed.
Each method call of the class new creates and defines a new lexical variable $data . Usually this variable (and the anonymous hash that it refers to) will go beyond the scope at the end of the routine and will be deleted. But in this case, new returns the subroutine reference to the calling code.
It is this calling code that stores the link that is transmitted. Calling any method of the new class is pretty pointless if the return object is not saved. In this case, the closure is deleted because nothing can access it anymore, and the $data variable and anonymous hash are also deleted for the same reason.
All Perl routine references are closures, regardless of whether the relevant data is used. It contains an implicit link to $data , which will be maintained as long as anything contains a link to this closure. All this means is the string
return $data->{$field};
will refer to the same $data that existed at the time new executed, so the hash is constant, and it can be populated and checked by calls to the close routine.
All other methods execute a subroutine from a closure using the specified first parameter. For example, a call
$person->name('trolley')
does Person::name($person, 'trolley') , which in turn removes $person from the @_ parameters @_ and calls it (because it is a subroutine reference), using the defined first parameter instead, and copying the rest an array of parameters, Like $person->('NAME', 'trolley') .
Hope this helps solve the correct interpretation of your question.