print "a Horse goes neigh!\n";
}
sub Sheep::speak {
- print "a Sheep goes baaaah!\n"
+ print "a Sheep goes baaaah!\n";
}
Cow::speak;
print "a Horse goes neigh!\n";
}
sub Sheep::speak {
- print "a Sheep goes baaaah!\n"
+ print "a Sheep goes baaaah!\n";
}
@pasture = qw(Cow Cow Horse Sheep Sheep);
sub sound { "moooo" }
sub speak {
my $class = shift;
- print "a $class goes ", $class->sound, "!\n"
+ print "a $class goes ", $class->sound, "!\n";
}
}
sub sound { "neigh" }
sub speak {
my $class = shift;
- print "a $class goes ", $class->sound, "!\n"
+ print "a $class goes ", $class->sound, "!\n";
}
}
{ package Animal;
sub speak {
my $class = shift;
- print "a $class goes ", $class->sound, "!\n"
+ print "a $class goes ", $class->sound, "!\n";
}
}
to have more than one parent class searched for the missing methods.
If C<Animal> also had an C<@ISA>, then we'd check there too. The
-search is recursive, depth-first, left-to-right in each C<@ISA>.
-Typically, each C<@ISA> has only one element (multiple elements means
-multiple inheritance and multiple headaches), so we get a nice tree of
-inheritance.
+search is recursive, depth-first, left-to-right in each C<@ISA> by
+default (see L<mro> for alternatives). Typically, each C<@ISA> has
+only one element (multiple elements means multiple inheritance and
+multiple headaches), so we get a nice tree of inheritance.
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
@Cow::ISA = qw(Animal);
+Or declare it as package global variable:
+
+ package Cow;
+ our @ISA = qw(Animal);
+
Or allow it as an implicitly named package variable:
package Cow;
Also note that the C<Animal> classname is now hardwired into the
subroutine selection. This is a mess if someone maintains the code,
-changing C<@ISA> for <Mouse> and didn't notice C<Animal> there in
+changing C<@ISA> for C<Mouse> and didn't notice C<Animal> there in
C<speak>. So, this is probably not the right way to go.
=head2 Starting the search from a different place
}
So, C<SUPER::speak> means look in the current package's C<@ISA> for
-C<speak>, invoking the first one found.
+C<speak>, invoking the first one found. Note that it does I<not> look in
+the C<@ISA> of C<$class>.
=head2 Where we're at so far...
{ package Animal;
sub speak {
my $class = shift;
- print "a $class goes ", $class->sound, "!\n"
+ print "a $class goes ", $class->sound, "!\n";
}
}
{ package Horse;
{ package Animal;
sub speak {
my $class = shift;
- print "a $class goes ", $class->sound, "!\n"
+ print "a $class goes ", $class->sound, "!\n";
}
sub name {
my $self = shift;
All we need is for a method to detect if it is being called on a class
or called on an instance. The most straightforward way is with the
C<ref> operator. This returns a string (the classname) when used on a
-blessed reference, and C<undef> when used on a string (like a
+blessed reference, and an empty string when used on a string (like a
classname). Let's modify the C<name> method first to notice the change:
sub name {
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<perltooc> (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