X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlboot.pod;h=927777d040826aac08b52032885e982e6daaf1e5;hb=e40b81a3dd247b1a29fc78399677b77b78b5f183;hp=dbf4fc998c94638fdfb34dfeb9e304a0fac45d4a;hpb=694468e388362429e0ea71cc051b563c183029a1;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlboot.pod b/pod/perlboot.pod index dbf4fc9..927777d 100644 --- a/pod/perlboot.pod +++ b/pod/perlboot.pod @@ -7,7 +7,7 @@ perlboot - Beginner's Object-Oriented Tutorial 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, a basic reference in using objects, and L, 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 @@ -67,7 +67,7 @@ Or is it? =head2 Introducing the method invocation arrow -For now, let's say that Cmethod> invokes subroutine +For now, let's say that C<< Class->method >> invokes subroutine C in package C. (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 @@ -139,8 +139,8 @@ attempts to invoke subroutine C as: (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 speaking subroutine -as: +first parameter (the only parameter, if no arguments are given). So +we can rewrite the C speaking subroutine as: sub Sheep::speak { my $class = shift; @@ -176,8 +176,8 @@ This method provides the constant text for the sound itself. } } -Now, when we call Cspeak>, we get a C<$class> of C in -C. This in turn selects the Csound> method, which +Now, when we call C<< Cow->speak >>, we get a C<$class> of C in +C. This in turn selects the C<< Cow->sound >> method, which returns C. But how different would this be for the C? { package Horse; @@ -214,7 +214,7 @@ with the animal-specific sound: Note the added C<@ISA> array. We'll get to that in a minute. -But what happens when we invoke Cspeak> now? +But what happens when we invoke C<< Cow->speak >> now? First, Perl constructs the argument list. In this case, it's just C. Then Perl looks for C. But that's not there, so @@ -227,7 +227,7 @@ with the already frozen argument list. Inside the C subroutine, C<$class> becomes C (the first argument). So when we get to the step of invoking -C<$class-Esound>, it'll be looking for Csound>, 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 @@ -245,14 +245,15 @@ inheritance. When we turn on C, 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); @@ -295,13 +296,13 @@ which results in: a Mouse goes squeak! [but you can barely hear it!] -Here, C has its own speaking routine, so Cspeak> -doesn't immediately invoke Cspeak>. This is known as +Here, C 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 was an C at all, since all of the methods needed for C are completely defined with C. -But we've now duplicated some of the code from Cspeak>, +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 does everything any other C does, but add in the extra comment? Sure! @@ -322,7 +323,7 @@ First, we can invoke the C method directly: Note that we have to include the C<$class> parameter (almost surely the value of C<"Mouse">) as the first parameter to C, since we've stopped using the method arrow. Why did we stop? Well, -if we invoke Cspeak> 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, it won't have the right class to come back to this package. @@ -381,7 +382,8 @@ listed in C<@ISA>) automatically: } So, C means look in the current package's C<@ISA> for -C, invoking the first one found. +C, invoking the first one found. Note that it does I look in +the C<@ISA> of C<$class>. =head2 Where we're at so far... @@ -429,7 +431,7 @@ and the C class: sub sound { "neigh" } } -This lets us invoke Cspeak> to ripple upward to +This lets us invoke C<< Horse->speak >> to ripple upward to C, calling back to C to get the specific sound, and the output of: @@ -490,7 +492,7 @@ If Horse::sound had not been found, we'd be wandering up the 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 @@ -506,7 +508,7 @@ the name: $$self; } } - + Now we call for the name: print $talking->name, " says ", $talking->sound, "\n"; @@ -552,6 +554,17 @@ C are C and C. The C operator 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 here, so that it quickly denotes +the constructor's argument as the name for this particular C. +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, with various ways of interpreting the arguments to +C. Either style is fine, as long as you document your particular +way of giving birth to an object. (And you I going to do that, +right?) + =head2 Inheriting the constructor But was there anything specific to C in that method? No. Therefore, @@ -695,8 +708,8 @@ Let's make a sheep that has a name and a color: my $bad = bless { Name => "Evil", Color => "black" }, Sheep; -so C<$bad-E{Name}> has C, and C<$bad-E{Color}> has -C. But we want to make C<$bad-Ename> access the name, and +so C<< $bad->{Name} >> has C, and C<< $bad->{Color} >> has +C. 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: @@ -778,9 +791,13 @@ Hopefully, this gets you started, though. For more information, see L (for all the gritty details about Perl objects, now that you've seen the basics), L (the -tutorial for those who already know objects), L (for some -more tricks), and books such as Damian Conway's excellent I. +tutorial for those who already know objects), L (dealing +with class data), L (for some more tricks), and books such as +Damian Conway's excellent I. + +Some modules which might prove interesting are Class::Accessor, +Class::Class, Class::Contract, Class::Data::Inheritable, +Class::MethodMaker and Tie::SecureHash =head1 COPYRIGHT