If you're not familiar with objects from other languages, some of the
other Perl object documentation may be a little daunting, such as
L<perlobj>, a basic reference in using objects, and L<perltoot>, which
-introduces readers to the pecularities of Perl's object system in a
+introduces readers to the peculiarities of Perl's object system in a
tutorial way.
So, let's take a different approach, presuming no prior object
=head2 Introducing the method invocation arrow
-For now, let's say that C<Class-E<gt>method> invokes subroutine
+For now, let's say that C<< Class->method >> invokes subroutine
C<method> in package C<Class>. (Here, "Class" is used in its
"category" meaning, not its "scholastic" meaning.) That's not
completely accurate, but we'll do this one step at a time. Now let's
(If the subroutine can't be found, "inheritance" kicks in, but we'll
get to that later.) This means that we get the class name as the
-first parameter. So we can rewrite the C<Sheep> speaking subroutine
-as:
+first parameter (the only parameter, if no arguments are given). So
+we can rewrite the C<Sheep> speaking subroutine as:
sub Sheep::speak {
my $class = shift;
}
}
-Now, when we call C<Cow-E<gt>speak>, we get a C<$class> of C<Cow> in
-C<speak>. This in turn selects the C<Cow-E<gt>sound> method, which
+Now, when we call C<< Cow->speak >>, we get a C<$class> of C<Cow> in
+C<speak>. This in turn selects the C<< Cow->sound >> method, which
returns C<moooo>. But how different would this be for the C<Horse>?
{ package Horse;
Note the added C<@ISA> array. We'll get to that in a minute.
-But what happens when we invoke C<Cow-E<gt>speak> now?
+But what happens when we invoke C<< Cow->speak >> now?
First, Perl constructs the argument list. In this case, it's just
C<Cow>. Then Perl looks for C<Cow::speak>. But that's not there, so
Inside the C<Animal::speak> subroutine, C<$class> becomes C<Cow> (the
first argument). So when we get to the step of invoking
-C<$class-E<gt>sound>, it'll be looking for C<Cow-E<gt>sound>, which
+C<< $class->sound >>, it'll be looking for C<< Cow->sound >>, which
gets it on the first try without looking at C<@ISA>. Success!
=head2 A few notes about @ISA
When we turn on C<use strict>, we'll get complaints on C<@ISA>, since
it's not a variable containing an explicit package name, nor is it a
-lexical ("my") variable. We can't make it a lexical variable though,
+lexical ("my") variable. We can't make it a lexical variable though
+(it has to belong to the package to be found by the inheritance mechanism),
so there's a couple of straightforward ways to handle that.
The easiest is to just spell the package name out:
@Cow::ISA = qw(Animal);
-Or allow it as an implictly named package variable:
+Or allow it as an implicitly named package variable:
package Cow;
use vars qw(@ISA);
a Mouse goes squeak!
[but you can barely hear it!]
-Here, C<Mouse> has its own speaking routine, so C<Mouse-E<gt>speak>
-doesn't immediately invoke C<Animal-E<gt>speak>. This is known as
+Here, C<Mouse> has its own speaking routine, so C<< Mouse->speak >>
+doesn't immediately invoke C<< Animal->speak >>. This is known as
"overriding". In fact, we didn't even need to say that a C<Mouse> was
an C<Animal> at all, since all of the methods needed for C<speak> are
completely defined with C<Mouse>.
-But we've now duplicated some of the code from C<Animal-E<gt>speak>,
+But we've now duplicated some of the code from C<< Animal->speak >>,
and this can once again be a maintenance headache. So, can we avoid
that? Can we say somehow that a C<Mouse> does everything any other
C<Animal> does, but add in the extra comment? Sure!
Note that we have to include the C<$class> parameter (almost surely
the value of C<"Mouse">) as the first parameter to C<Animal::speak>,
since we've stopped using the method arrow. Why did we stop? Well,
-if we invoke C<Animal-E<gt>speak> there, the first parameter to the
+if we invoke C<< Animal->speak >> there, the first parameter to the
method will be C<"Animal"> not C<"Mouse">, and when time comes for it
to call for the C<sound>, it won't have the right class to come back
to this package.
sub sound { "neigh" }
}
-This lets us invoke C<Horse-E<gt>speak> to ripple upward to
+This lets us invoke C<< Horse->speak >> to ripple upward to
C<Animal::speak>, calling back to C<Horse::sound> to get the specific
sound, and the output of:
C<@Horse::ISA> list to try to find the method in one of the
superclasses, just as for a class method. The only difference between
a class method and an instance method is whether the first parameter
-is a instance (a blessed reference) or a class name (a string).
+is an instance (a blessed reference) or a class name (a string).
=head2 Accessing the instance data
$$self;
}
}
-
+
Now we call for the name:
print $talking->name, " says ", $talking->sound, "\n";
not only blesses C<$name>, it also returns the reference to C<$name>,
so that's fine as a return value. And that's how to build a horse.
+We've called the constructor C<named> here, so that it quickly denotes
+the constructor's argument as the name for this particular C<Horse>.
+You can use different constructors with different names for different
+ways of "giving birth" to the object (like maybe recording its
+pedigree or date of birth). However, you'll find that most people
+coming to Perl from more limited languages use a single constructor
+named C<new>, with various ways of interpreting the arguments to
+C<new>. Either style is fine, as long as you document your particular
+way of giving birth to an object. (And you I<were> going to do that,
+right?)
+
=head2 Inheriting the constructor
But was there anything specific to C<Horse> in that method? No. Therefore,
my $bad = bless { Name => "Evil", Color => "black" }, Sheep;
-so C<$bad-E<gt>{Name}> has C<Evil>, and C<$bad-E<gt>{Color}> has
-C<black>. But we want to make C<$bad-E<gt>name> access the name, and
+so C<< $bad->{Name} >> has C<Evil>, and C<< $bad->{Color} >> has
+C<black>. But we want to make C<< $bad->name >> access the name, and
that's now messed up because it's expecting a scalar reference. Not
to worry, because that's pretty easy to fix up:
For more information, see L<perlobj> (for all the gritty details about
Perl objects, now that you've seen the basics), L<perltoot> (the
-tutorial for those who already know objects), L<perlbot> (for some
-more tricks), and books such as Damian Conway's excellent I<Object
-Oriented Perl>.
+tutorial for those who already know objects), L<perltootc> (dealing
+with class data), L<perlbot> (for some more tricks), and books such as
+Damian Conway's excellent I<Object Oriented Perl>.
+
+Some modules which might prove interesting are Class::Accessor,
+Class::Class, Class::Contract, Class::Data::Inheritable,
+Class::MethodMaker and Tie::SecureHash
=head1 COPYRIGHT