But it doesn't.
With tie, a hash is just an API. And it's a good API for any object that has settable-gettables, because it's familiar and can be used in all the ways that Perl users know and love (subject to any restrictions you program in, of course). It also encapsulates your object completely: all access is necessarily through the API.
That's it. What follows is some example code of minimal objects implemented in the getter-setter way, and then using a hash API. You can see that the code is very similar. Both implementations use an array as the actual base type.
Update: I should add that the code below is not intended to be a blueprint for writing classes. It is only to illustrate the notion that a hash can be an API rather than an implementation. There are a number of issues to address (pointed out by respondants already) to make a workable, general-purpose foundation.
use warnings; use strict; package MyThing; sub new { my $class = shift; bless [], $class; } sub set_foo { my ($self, $newfoo) = @_; $self->[0] = $newfoo; } sub get_foo { $_[0]->[0]; } package HashAPI; sub TIEHASH { my $class = shift; bless [], $class; } sub STORE { my ($self, $key, $val) = @_; unless ($key eq 'foo') { die "No $key member\n"; } $self->[0] = $val; } sub FETCH { my ($self, $key, $val) = @_; unless ($key eq 'foo') { die "No $key member\n"; } $self->[0]; } sub new { my $class = shift; tie my(%obj), $class; bless \%obj, $class; } package main; my $clunker = MyThing->new(); my $slick = HashAPI->new(); $clunker->set_foo('Some value'); print $clunker->get_foo, "\n"; $slick->{foo} = 'Some value'; print $slick->{foo}, "\n";
|
|---|