Perl doesn't impose restrictions on who gets to use which methods. The public-versus-private distinction is by convention, not syntax. (Well, unless you use the Alias module described below in Data Members as Variables.) Occasionally you'll see method names beginning or ending with an underscore or two. This marking is a convention indicating that the methods are private to that class alone and sometimes to its closest acquaintances, its immediate subclasses. But this distinction is not enforced by Perl itself. It's up to the programmer to behave.
There's no reason to limit methods to those that simply access data. Methods can do anything at all. The key point is that they're invoked against an object or a class. Let's say we'd like object methods that do more than fetch or set one particular field.
sub exclaim { my $self = shift; return sprintf "Hi, I'm %s, age %d, working with %s", $self->{NAME}, $self->{AGE}, join(", ", $self->{PEERS}); }
Or maybe even one like this:
sub happy_birthday { my $self = shift; return ++$self->{AGE}; }
Some might argue that one should go at these this way:
sub exclaim { my $self = shift; return sprintf "Hi, I'm %s, age %d, working with %s", $self->name, $self->age, join(", ", $self->peers); }
sub happy_birthday { my $self = shift; return $self->age( $self->age() + 1 ); }
But since these methods are all executing in the class itself, this may not be critical. There are trade-offs to be made. Using direct hash access is faster (about an order of magnitude faster, in fact), and it's more convenient when you want to interpolate in strings. But using methods (the external interface) internally shields not just the users of your class but even you yourself from changes in your data representation.