reference work too complicated, a tutorial on object-oriented programming
in Perl can be found in L<perltoot>.
-If you're still with us, then
+If you're still with us, then
here are three very simple definitions that you should find reassuring.
=over 4
package Critter;
sub new { bless {} }
-The C<{}> constructs a reference to an anonymous hash containing no
+The C<{}> constructs a reference to an anonymous hash containing no
key/value pairs. The bless() takes that reference and tells the object
it references that it's now a Critter, and returns the reference.
This is for convenience, because the referenced object itself knows that
-it has been blessed, and its reference to it could have been returned
+it has been blessed, and the reference to it could have been returned
directly, like this:
sub new {
Or if you expect people to call not just C<CLASS-E<gt>new()> but also
C<$obj-E<gt>new()>, then use something like this. The initialize()
-method used will be of whatever $class we blessed the
+method used will be of whatever $class we blessed the
object into:
sub new {
A constructor may re-bless a referenced object currently belonging to
another class, but then the new class is responsible for all cleanup
later. The previous blessing is forgotten, as an object may belong
-to only one class at a time. (Although of course it's free to
+to only one class at a time. (Although of course it's free to
inherit methods from many classes.)
A clarification: Perl objects are blessed. References are not. Objects
bless $a, BLAH;
print "\$b is a ", ref($b), "\n";
-This reports $b as being a BLAH, so obviously bless()
+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
@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
-through @ISA are known as base classes of the current class.
+through @ISA are known as base classes of the current class.
If a missing method is found in one of the base classes, it is cached
in the current class for efficiency. Changing @ISA or defining new
definition. (It does provide a little syntax for method invocation
though. More on that later.) A method expects its first argument
to be the object or package it is being invoked on. There are just two
-types of methods, which we'll call class and instance.
+types of methods, which we'll call class and instance.
(Sometimes you'll hear these called static and virtual, in honor of
the two C++ method types they most closely resemble.)
=item isa(CLASS)
-C<isa> returns I<true> if its object is blessed into a sub-class of C<CLASS>
+C<isa> returns I<true> if its object is blessed into a subclass of C<CLASS>
C<isa> is also exportable and can be called as a sub with two arguments. This
allows the ability to check what a reference points to. Example
available to your program. This is necessary only if you wish to
have C<isa> available as a plain subroutine in the current package.
-=head2 Destructors
+=head2 Destructors
When the last reference to an object goes away, the object is
automatically destroyed. (This may even be after you exit, if you've
stored references in global variables.) If you want to capture control
just before the object is freed, you may define a DESTROY method in
your class. It will automatically be called at the appropriate moment,
-and you can do any extra cleanup you need to do.
-
-Perl doesn't do nested destruction for you. If your constructor
-re-blessed a reference from one of your base classes, your DESTROY may
-need to call DESTROY for any base classes that need it. But this applies
-to only re-blessed objects--an object reference that is merely
-I<CONTAINED> in the current object will be freed and destroyed
-automatically when the current object is freed.
+and you can do any extra cleanup you need to do. Perl passes a reference
+to the object under destruction as the first (and only) argument. Beware
+that the reference is a read-only value, and cannot be modified by
+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.
+
+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
+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.
+
+Do not confuse the foregoing with how objects I<CONTAINED> 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
+elsewhere.
=head2 WARNING
An indirect object is limited to a name, a scalar variable, or a block,
because it would have to do too much lookahead otherwise, just like any
other postfix dereference in the language. The left side of -E<gt> is not so
-limited, because it's an infix operator, not a postfix operator.
+limited, because it's an infix operator, not a postfix operator.
-That means that below, A and B are equivalent to each other, and C and D
-are equivalent, but AB and CD are different:
+That means that in the following, A and B are equivalent to each other, and
+C and D are equivalent, but A/B and C/D are different:
- A: method $obref->{"fieldname"}
+ A: method $obref->{"fieldname"}
B: (method $obref)->{"fieldname"}
- C: $obref->{"fieldname"}->method()
+ C: $obref->{"fieldname"}->method()
D: method {$obref->{"fieldname"}}
=head2 Summary
A more serious concern is that unreachable memory with a non-zero
reference count will not normally get freed. Therefore, this is a bad
-idea:
+idea:
{
my $a;
$a = \$a;
- }
+ }
Even thought $a I<should> go away, it can't. When building recursive data
structures, you'll have to break the self-reference yourself explicitly
$node->{LEFT} = $node->{RIGHT} = $node;
$node->{DATA} = [ @_ ];
return bless $node => $class;
- }
+ }
If you create nodes like that, they (currently) won't go away unless you
break their self reference yourself. (In other words, this is not to be
exits), then a rather costly but complete mark-and-sweep style of garbage
collection is performed, and everything allocated by that thread gets
destroyed. This is essential to support Perl as an embedded or a
-multi-threadable language. For example, this program demonstrates Perl's
+multithreadable language. For example, this program demonstrates Perl's
two-phased garbage collection:
- #!/usr/bin/perl
+ #!/usr/bin/perl
package Subtle;
sub new {
$test = \$test;
warn "CREATING " . \$test;
return bless \$test;
- }
+ }
sub DESTROY {
my $self = shift;
warn "DESTROYING $self";
- }
+ }
package main;
my $b = Subtle->new;
$$a = 0; # break selfref
warn "leaving block";
- }
+ }
warn "just exited block";
warn "time to die...";
DESTROYING Subtle=SCALAR(0x8e57c) during global destruction.
Notice that "global destruction" bit there? That's the thread
-garbage collector reaching the unreachable.
+garbage collector reaching the unreachable.
Objects are always destructed, even when regular refs aren't and in fact
are destructed in a separate pass before ordinary refs just to try to
=head1 SEE ALSO
-A kinder, gentler tutorial on object-oriented programming in Perl can
+A kinder, gentler tutorial on object-oriented programming in Perl can
be found in L<perltoot>.
-You should also check out L<perlbot> for other object tricks, traps, and tips,
-as well as L<perlmod> for some style guides on constructing both modules
+You should also check out L<perlbot> for other object tricks, traps, and tips,
+as well as L<perlmodlib> for some style guides on constructing both modules
and classes.