Приглашаем посетить
Куприн (kuprin-lit.ru)

Section 12.8.  More Interesting Instances

Previous
Table of Contents
Next

12.8. More Interesting Instances

What if an instance needs more data? Most interesting instances are made of many items, each of which can, in turn, be a reference or another object. The easiest way to store these items is often in a hash. The keys of the hash serve as the names of parts of the object (also called instance or member variables), and the corresponding values are, well, the values.

How do we turn the horse into a hash?[*] Recall that an object is any blessed reference. We can just as easily make it a blessed hash reference as a blessed scalar reference, as long as everything that looks at the reference is changed accordingly.

[*] Other than calling on a butcher, that is.

Let's make a sheep that has a name and a color:

my $lost = bless { Name => 'Bo', Color => 'white' }, Sheep;

$lost->{Name} has Bo, and $lost->{Color} has white. But we want to make $lost->name access the name, and that's now messed up because it's expecting a scalar reference. Not to worry, because it's pretty easy to fix:

## in Animal
sub name {
  my $either = shift;
  ref $either
    ? $either->{Name}
    : "an unnamed $either";
}

named still builds a scalar sheep, so let's fix that as well:

## in Animal
sub named {
  my $class = shift;
  my $name = shift;
  my $self = { Name => $name, Color => $class->default_color };
  bless $self, $class;
}

What's this default_color? If named has only the name, we still need to set a color, so we'll have a class-specific initial color. For a sheep, we might define it as white:

## in Sheep
sub default_color { 'white' }

Then, to keep from having to define one for each additional class, define a backstop method, which serves as the "default default," directly in Animal:

## in Animal
sub default_color { 'brown' }

Thus, all animals are brown (muddy, perhaps), unless a specific animal class gives a specific override to this method.

Now, because name and named were the only methods that referenced the structure of the object, the remaining methods can stay the same, so speak still works as before. This supports another basic rule of OOP: if only the object accesses its internal data, there's less code to change when it's time to modify that structure.


Previous
Table of Contents
Next