X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlobj.pod;h=fdecd84a6882ed8294d8f916f9a05d6ac5c67388;hb=3387927231e5bf4138a3082ecafb247e03a8061a;hp=16013fc9030c735c81523281ac812038d9d356c3;hpb=029f3b4481eb14b016dea8aa8fb43279a710daa3;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlobj.pod b/pod/perlobj.pod index 16013fc..fdecd84 100644 --- a/pod/perlobj.pod +++ b/pod/perlobj.pod @@ -1,4 +1,5 @@ =head1 NAME +X X perlobj - Perl objects @@ -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 @@ -146,14 +151,16 @@ There is a special array within each package called @ISA, which says where else to look for a method if you can't find it in the current package. This is how Perl implements inheritance. Each element of the @ISA array is just the name of another package that happens to be a -class package. The classes are searched (depth first) for missing -methods in the order that they occur in @ISA. The classes accessible +class package. The classes are searched for missing methods in +depth-first, left-to-right order by default (see L for alternative +search order and other in-depth information). The classes accessible through @ISA are known as base classes of the current class. 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. +supplied in the UNIVERSAL class; see L<"Default UNIVERSAL methods"> or +L 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 +172,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 +191,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 +199,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 @@ -226,6 +237,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 +278,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,11 +288,12 @@ current class's C<@ISA> list. $self->SUPER::display("Name", @args); } -It is important to note that C refers to the superclass of the -I and not to the superclass of the object. Also, the +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 @@ -295,7 +309,25 @@ 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. + +If the right side of the arrow is a scalar containing a reference +to a subroutine, then this is equivalent to calling the referenced +subroutine directly with the class name or object on the left side +of the arrow as its first argument. No lookup is done and there is +no requirement that the subroutine be defined in any package related +to the class name or object on the left side of the arrow. + +For example, the following calls to $display are equivalent: + + my $display = sub { my $self = shift; ... }; + $fred->$display("Height", "Weight"); + $display->($fred, "Height", "Weight"); + =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 @@ -318,8 +350,8 @@ Usually Perl gets it right, but when it doesn't you get a function call compiled as a method, or vice versa. This can introduce subtle bugs that are hard to detect. -For example, a call to a method C in indirect notation -- as C++ -programmers are wont to make -- can be miscompiled into a subroutine +For example, a call to a method C in indirect notation (as C++ +programmers are wont to make) can be miscompiled into a subroutine call if there's already a C function in scope. You'd end up calling the current package's C as a subroutine, rather than the desired class's method. The compiler tries to cheat by remembering @@ -361,6 +393,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: @@ -368,68 +401,40 @@ 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 subroutine with two arguments. -The first does not need to be an object or even a reference. This -allows you to check what a reference points to, or whether -something is a reference of a given type. Example - - if(UNIVERSAL::isa($ref, 'ARRAY')) { - #... - } - -To determine if a reference is a blessed object, you can write +=item DOES(ROLE) +X - print "It's an object\n" if UNIVERSAL::isa($val, 'UNIVERSAL'); +C returns I if its object claims to perform the role C. By +default, this is equivalent to 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. So here's another way to check if a reference is a -blessed object - - print "It's still an object\n" if UNIVERSAL::can($val, 'can'); - -You can also use the C function of Scalar::Util: - - use Scalar::Util 'blessed'; - - my $blessing = blessed $suspected_object; - -C returns the name of the package the argument has been -blessed into, or C. +C is returned. =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 defined by the $VERSION variable in the given package) not less than -NEED; it will die if this is not the case. This method is normally -called as a class method. This method is called automatically by the -C form of C. +NEED; it will die if this is not the case. This method is called automatically +by the C form of C. - use A 1.2 qw(some imported subs); + use Package 1.2 qw(some imported subs); # implies: - A->VERSION(1.2); + Package->VERSION(1.2); =back -B C directly uses Perl's internal code for method lookup, and -C uses a very similar method and cache-ing strategy. This may cause -strange effects if the Perl code dynamically changes @ISA in any package. - -You may add other methods to the UNIVERSAL class via Perl or XS code. -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 @@ -443,6 +448,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 @@ -450,6 +460,15 @@ object destruction, or for ensuring that destructors in the base classes of your choosing get called. Explicitly calling DESTROY is also possible, but is usually never needed. +DESTROY is subject to AUTOLOAD lookup, just like any other method. Hence, if +your class has an AUTOLOAD method, but does not need any DESTROY actions, +you probably want to provide a DESTROY method anyway, to prevent an +expensive call to AUTOLOAD each time an object is freed. As this technique +makes empty DESTROY methods common, the implementation is optimised so that +a DESTROY method that is an empty or constant subroutine, and hence could +have no side effects anyway, is not actually called. +X X + Do not confuse the previous discussion with how objects I in the current one are destroyed. Such objects will be freed and destroyed automatically when the current object is freed, provided no other references to them exist @@ -462,6 +481,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 @@ -485,9 +506,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; @@ -535,15 +555,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