X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlobj.pod;h=6cfa20ce8ef2d70671a6c54a6f4d6eb3c75f50ef;hb=53ae2428795d0b9d42a1657c22c5f1b557784379;hp=f31ce2c993fa1b78a0096ba59630fe59779d978a;hpb=38242c004862c1bab670bd395f573231149ffa1a;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlobj.pod b/pod/perlobj.pod index f31ce2c..6cfa20c 100644 --- a/pod/perlobj.pod +++ b/pod/perlobj.pod @@ -1,4 +1,5 @@ =head1 NAME +X X perlobj - Perl objects @@ -7,7 +8,7 @@ perlobj - Perl objects First you need to understand what references are in Perl. See L for that. Second, if you still find the following reference work too complicated, a tutorial on object-oriented programming -in Perl can be found in L and L. +in Perl can be found in L and L. If you're still with us, then here are three very simple definitions that you should find reassuring. @@ -34,6 +35,7 @@ a package name, for class methods) as the first argument. We'll cover these points now in more depth. =head2 An Object is Simply a Reference +X X X X Unlike say C++, Perl doesn't provide any special syntax for constructors. A constructor is merely a subroutine that returns a @@ -97,9 +99,11 @@ so that your constructors may be inherited: } Or if you expect people to call not just C<< CLASS->new() >> but also -C<< $obj->new() >>, then use something like this. The initialize() -method used will be of whatever $class we blessed the -object into: +C<< $obj->new() >>, then use something like the following. (Note that using +this to call new() on an instance does not automatically perform any +copying. If you want a shallow or deep copy of an object, you'll have to +specifically allow for that.) The initialize() method used will be of +whatever $class we blessed the object into: sub new { my $this = shift; @@ -137,6 +141,7 @@ This reports $b as being a BLAH, so obviously bless() operated on the object and not on the reference. =head2 A Class is Simply a Package +X X X<@ISA> X Unlike say C++, Perl doesn't provide any special syntax for class definitions. You use a package as a class by putting method @@ -154,6 +159,7 @@ All classes implicitly inherit from class C as their last base class. Several commonly used methods are automatically supplied in the UNIVERSAL class; see L<"Default UNIVERSAL methods"> for more details. +X X X If a missing method is found in a base class, it is cached in the current class for efficiency. Changing @ISA or defining new @@ -165,10 +171,12 @@ all over again, this time looking for a method named AUTOLOAD(). If an AUTOLOAD is found, this method is called on behalf of the missing method, setting the package global $AUTOLOAD to be the fully qualified name of the method that was intended to be called. +X If none of that works, Perl finally gives up and complains. If you want to stop the AUTOLOAD inheritance say simply +X sub AUTOLOAD; @@ -182,6 +190,7 @@ by the various classes that might want to do something with the object. The only problem with this is that you can't sure that you aren't using a piece of the hash that isn't already used. A reasonable workaround is to prepend your fieldname in the hash with the package name. +X X sub bump { my $self = shift; @@ -189,6 +198,7 @@ is to prepend your fieldname in the hash with the package name. } =head2 A Method is Simply a Subroutine +X Unlike say C++, Perl doesn't provide any special syntax for method definition. (It does provide a little syntax for method invocation @@ -200,7 +210,7 @@ methods and instance methods. A class method expects a class name as the first argument. It provides functionality for the class as a whole, not for any individual object belonging to the class. Constructors are often -class methods, but see L and L for alternatives. +class methods, but see L and L for alternatives. Many class methods simply ignore their first argument, because they already know what package they're in and don't care what package they were invoked via. (These aren't necessarily the same, because @@ -226,6 +236,7 @@ and then uses that as an ordinary reference. } =head2 Method Invocation +X X X X<< -> >> For various historical and other reasons, Perl offers two equivalent ways to write a method call. The simpler and more common way is to use @@ -266,6 +277,7 @@ to start looking for the subroutines in C. As a special case of the above, you may use the C pseudo-class to tell Perl to start looking for the method in the packages named in the current class's C<@ISA> list. +X package MyCritter; use base 'Critter'; # sets @MyCritter::ISA = ('Critter'); @@ -275,6 +287,17 @@ current class's C<@ISA> list. $self->SUPER::display("Name", @args); } +It is important to note that C refers to the superclass(es) of the +I and not to the superclass(es) of the object. Also, the +C pseudo-class can only currently be used as a modifier to a method +name, but not in any of the other ways that class names are normally used, +eg: +X + + something->SUPER::method(...); # OK + SUPER::method(...); # WRONG + SUPER->method(...); # WRONG + Instead of a class name or an object reference, you can also use any expression that returns either of those on the left side of the arrow. So the following statement is valid: @@ -285,7 +308,12 @@ and so is the following: my $fred = (reverse "rettirC")->find(reverse "derF"); +The right side of the arrow typically is the method name, but a simple +scalar variable containing either the method name or a subroutine +reference can also be used. + =head2 Indirect Object Syntax +X X X The other way to invoke a method is by using the so-called "indirect object" notation. This syntax was available in Perl 4 long before @@ -351,6 +379,7 @@ to read code using the indirect object notation, so it's important to be familiar with it. =head2 Default UNIVERSAL methods +X The C package automatically contains the following methods that are inherited by all other classes: @@ -358,25 +387,38 @@ are inherited by all other classes: =over 4 =item isa(CLASS) +X C returns I if its object is blessed into a subclass of C -You can also call C as a sub with two arguments. The -first does not need to be an object or even a reference. This -allows the ability to check what a reference points to, or whether -something is a reference of a given type. Example +You can also call C as a subroutine with two arguments. Of +course, this will do the wrong thing if someone has overridden C in a +class, so don't do it. - if(UNIVERSAL::isa($ref, 'ARRAY')) { - #... +If you need to determine whether you've received a valid invocant, use the +C function from L: +X X + + if (blessed($ref) && $ref->isa( 'Some::Class')) { + # ... } +C returns the name of the package the argument has been +blessed into, or C. + =item can(METHOD) +X C checks to see if its object has a method called C, if it does then a reference to the sub is returned, if it does not then I is returned. +C can also be called as a subroutine with two arguments. It'll +always return I if its first argument isn't an object or a class name. +The same caveats for calling C directly apply here, too. + =item VERSION( [NEED] ) +X C returns the version number of the class (package). If the NEED argument is given then it will check that the current version (as @@ -400,6 +442,7 @@ You do not need to C to make these methods available to your program (and you should not do so). =head2 Destructors +X X When the last reference to an object goes away, the object is automatically destroyed. (This may even be after you exit, if you've @@ -413,6 +456,11 @@ manipulating C<$_[0]> within the destructor. The object itself (i.e. the thingy the reference points to, namely C<${$_[0]}>, C<@{$_[0]}>, C<%{$_[0]}> etc.) is not similarly constrained. +Since DESTROY methods can be called at unpredictable times, it is +important that you localise any global variables that the method may +update. In particular, localise C<$@> if you use C and +localise C<$?> if you use C or backticks. + If you arrange to re-bless the reference before the destructor returns, perl will again call the DESTROY method for the re-blessed object after the current one returns. This can be used for clean delegation of @@ -432,6 +480,8 @@ book about object-oriented design methodology, and bang your forehead with it for the next six months or so. =head2 Two-Phased Garbage Collection +X X X +X X X For most purposes, Perl uses a fast and simple, reference-based garbage collection system. That means there's an extra @@ -455,9 +505,8 @@ if you don't care to leak. For example, here's a self-referential node such as one might use in a sophisticated tree structure: sub new_node { - my $self = shift; - my $class = ref($self) || $self; - my $node = {}; + my $class = shift; + my $node = {}; $node->{LEFT} = $node->{RIGHT} = $node; $node->{DATA} = [ @_ ]; return bless $node => $class; @@ -505,15 +554,15 @@ two-phased garbage collection: warn "time to die..."; exit; -When run as F, the following output is produced: +When run as F, the following output is produced: - starting program at /tmp/test line 18. - CREATING SCALAR(0x8e5b8) at /tmp/test line 7. - CREATING SCALAR(0x8e57c) at /tmp/test line 7. - leaving block at /tmp/test line 23. - DESTROYING Subtle=SCALAR(0x8e5b8) at /tmp/test line 13. - just exited block at /tmp/test line 26. - time to die... at /tmp/test line 27. + starting program at /foo/test line 18. + CREATING SCALAR(0x8e5b8) at /foo/test line 7. + CREATING SCALAR(0x8e57c) at /foo/test line 7. + leaving block at /foo/test line 23. + DESTROYING Subtle=SCALAR(0x8e5b8) at /foo/test line 13. + just exited block at /foo/test line 26. + time to die... at /foo/test line 27. DESTROYING Subtle=SCALAR(0x8e57c) during global destruction. Notice that "global destruction" bit there? That's the thread @@ -539,7 +588,7 @@ breaks the circularities in the self-referential structure. =head1 SEE ALSO A kinder, gentler tutorial on object-oriented programming in Perl can -be found in L, L and L. You should +be found in L, L and L. You should also check out L for other object tricks, traps, and tips, as well as L for some style guides on constructing both modules and classes.