xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/pod/perlbot.pod (revision 0:68f95e015346)
1*0Sstevel@tonic-gate=head1 NAME
2*0Sstevel@tonic-gate
3*0Sstevel@tonic-gateperlbot - Bag'o Object Tricks (the BOT)
4*0Sstevel@tonic-gate
5*0Sstevel@tonic-gate=head1 DESCRIPTION
6*0Sstevel@tonic-gate
7*0Sstevel@tonic-gateThe following collection of tricks and hints is intended to whet curious
8*0Sstevel@tonic-gateappetites about such things as the use of instance variables and the
9*0Sstevel@tonic-gatemechanics of object and class relationships.  The reader is encouraged to
10*0Sstevel@tonic-gateconsult relevant textbooks for discussion of Object Oriented definitions and
11*0Sstevel@tonic-gatemethodology.  This is not intended as a tutorial for object-oriented
12*0Sstevel@tonic-gateprogramming or as a comprehensive guide to Perl's object oriented features,
13*0Sstevel@tonic-gatenor should it be construed as a style guide.  If you're looking for tutorials,
14*0Sstevel@tonic-gatebe sure to read L<perlboot>, L<perltoot>, and L<perltooc>.
15*0Sstevel@tonic-gate
16*0Sstevel@tonic-gateThe Perl motto still holds:  There's more than one way to do it.
17*0Sstevel@tonic-gate
18*0Sstevel@tonic-gate=head1 OO SCALING TIPS
19*0Sstevel@tonic-gate
20*0Sstevel@tonic-gate=over 5
21*0Sstevel@tonic-gate
22*0Sstevel@tonic-gate=item 1
23*0Sstevel@tonic-gate
24*0Sstevel@tonic-gateDo not attempt to verify the type of $self.  That'll break if the class is
25*0Sstevel@tonic-gateinherited, when the type of $self is valid but its package isn't what you
26*0Sstevel@tonic-gateexpect.  See rule 5.
27*0Sstevel@tonic-gate
28*0Sstevel@tonic-gate=item 2
29*0Sstevel@tonic-gate
30*0Sstevel@tonic-gateIf an object-oriented (OO) or indirect-object (IO) syntax was used, then the
31*0Sstevel@tonic-gateobject is probably the correct type and there's no need to become paranoid
32*0Sstevel@tonic-gateabout it.  Perl isn't a paranoid language anyway.  If people subvert the OO
33*0Sstevel@tonic-gateor IO syntax then they probably know what they're doing and you should let
34*0Sstevel@tonic-gatethem do it.  See rule 1.
35*0Sstevel@tonic-gate
36*0Sstevel@tonic-gate=item 3
37*0Sstevel@tonic-gate
38*0Sstevel@tonic-gateUse the two-argument form of bless().  Let a subclass use your constructor.
39*0Sstevel@tonic-gateSee L<INHERITING A CONSTRUCTOR>.
40*0Sstevel@tonic-gate
41*0Sstevel@tonic-gate=item 4
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gateThe subclass is allowed to know things about its immediate superclass, the
44*0Sstevel@tonic-gatesuperclass is allowed to know nothing about a subclass.
45*0Sstevel@tonic-gate
46*0Sstevel@tonic-gate=item 5
47*0Sstevel@tonic-gate
48*0Sstevel@tonic-gateDon't be trigger happy with inheritance.  A "using", "containing", or
49*0Sstevel@tonic-gate"delegation" relationship (some sort of aggregation, at least) is often more
50*0Sstevel@tonic-gateappropriate.  See L<OBJECT RELATIONSHIPS>, L<USING RELATIONSHIP WITH SDBM>,
51*0Sstevel@tonic-gateand L<"DELEGATION">.
52*0Sstevel@tonic-gate
53*0Sstevel@tonic-gate=item 6
54*0Sstevel@tonic-gate
55*0Sstevel@tonic-gateThe object is the namespace.  Make package globals accessible via the
56*0Sstevel@tonic-gateobject.  This will remove the guess work about the symbol's home package.
57*0Sstevel@tonic-gateSee L<CLASS CONTEXT AND THE OBJECT>.
58*0Sstevel@tonic-gate
59*0Sstevel@tonic-gate=item 7
60*0Sstevel@tonic-gate
61*0Sstevel@tonic-gateIO syntax is certainly less noisy, but it is also prone to ambiguities that
62*0Sstevel@tonic-gatecan cause difficult-to-find bugs.  Allow people to use the sure-thing OO
63*0Sstevel@tonic-gatesyntax, even if you don't like it.
64*0Sstevel@tonic-gate
65*0Sstevel@tonic-gate=item 8
66*0Sstevel@tonic-gate
67*0Sstevel@tonic-gateDo not use function-call syntax on a method.  You're going to be bitten
68*0Sstevel@tonic-gatesomeday.  Someone might move that method into a superclass and your code
69*0Sstevel@tonic-gatewill be broken.  On top of that you're feeding the paranoia in rule 2.
70*0Sstevel@tonic-gate
71*0Sstevel@tonic-gate=item 9
72*0Sstevel@tonic-gate
73*0Sstevel@tonic-gateDon't assume you know the home package of a method.  You're making it
74*0Sstevel@tonic-gatedifficult for someone to override that method.  See L<THINKING OF CODE REUSE>.
75*0Sstevel@tonic-gate
76*0Sstevel@tonic-gate=back
77*0Sstevel@tonic-gate
78*0Sstevel@tonic-gate=head1 INSTANCE VARIABLES
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gateAn anonymous array or anonymous hash can be used to hold instance
81*0Sstevel@tonic-gatevariables.  Named parameters are also demonstrated.
82*0Sstevel@tonic-gate
83*0Sstevel@tonic-gate	package Foo;
84*0Sstevel@tonic-gate
85*0Sstevel@tonic-gate	sub new {
86*0Sstevel@tonic-gate		my $type = shift;
87*0Sstevel@tonic-gate		my %params = @_;
88*0Sstevel@tonic-gate		my $self = {};
89*0Sstevel@tonic-gate		$self->{'High'} = $params{'High'};
90*0Sstevel@tonic-gate		$self->{'Low'}  = $params{'Low'};
91*0Sstevel@tonic-gate		bless $self, $type;
92*0Sstevel@tonic-gate	}
93*0Sstevel@tonic-gate
94*0Sstevel@tonic-gate
95*0Sstevel@tonic-gate	package Bar;
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gate	sub new {
98*0Sstevel@tonic-gate		my $type = shift;
99*0Sstevel@tonic-gate		my %params = @_;
100*0Sstevel@tonic-gate		my $self = [];
101*0Sstevel@tonic-gate		$self->[0] = $params{'Left'};
102*0Sstevel@tonic-gate		$self->[1] = $params{'Right'};
103*0Sstevel@tonic-gate		bless $self, $type;
104*0Sstevel@tonic-gate	}
105*0Sstevel@tonic-gate
106*0Sstevel@tonic-gate	package main;
107*0Sstevel@tonic-gate
108*0Sstevel@tonic-gate	$a = Foo->new( 'High' => 42, 'Low' => 11 );
109*0Sstevel@tonic-gate	print "High=$a->{'High'}\n";
110*0Sstevel@tonic-gate	print "Low=$a->{'Low'}\n";
111*0Sstevel@tonic-gate
112*0Sstevel@tonic-gate	$b = Bar->new( 'Left' => 78, 'Right' => 40 );
113*0Sstevel@tonic-gate	print "Left=$b->[0]\n";
114*0Sstevel@tonic-gate	print "Right=$b->[1]\n";
115*0Sstevel@tonic-gate
116*0Sstevel@tonic-gate=head1 SCALAR INSTANCE VARIABLES
117*0Sstevel@tonic-gate
118*0Sstevel@tonic-gateAn anonymous scalar can be used when only one instance variable is needed.
119*0Sstevel@tonic-gate
120*0Sstevel@tonic-gate	package Foo;
121*0Sstevel@tonic-gate
122*0Sstevel@tonic-gate	sub new {
123*0Sstevel@tonic-gate		my $type = shift;
124*0Sstevel@tonic-gate		my $self;
125*0Sstevel@tonic-gate		$self = shift;
126*0Sstevel@tonic-gate		bless \$self, $type;
127*0Sstevel@tonic-gate	}
128*0Sstevel@tonic-gate
129*0Sstevel@tonic-gate	package main;
130*0Sstevel@tonic-gate
131*0Sstevel@tonic-gate	$a = Foo->new( 42 );
132*0Sstevel@tonic-gate	print "a=$$a\n";
133*0Sstevel@tonic-gate
134*0Sstevel@tonic-gate
135*0Sstevel@tonic-gate=head1 INSTANCE VARIABLE INHERITANCE
136*0Sstevel@tonic-gate
137*0Sstevel@tonic-gateThis example demonstrates how one might inherit instance variables from a
138*0Sstevel@tonic-gatesuperclass for inclusion in the new class.  This requires calling the
139*0Sstevel@tonic-gatesuperclass's constructor and adding one's own instance variables to the new
140*0Sstevel@tonic-gateobject.
141*0Sstevel@tonic-gate
142*0Sstevel@tonic-gate	package Bar;
143*0Sstevel@tonic-gate
144*0Sstevel@tonic-gate	sub new {
145*0Sstevel@tonic-gate		my $type = shift;
146*0Sstevel@tonic-gate		my $self = {};
147*0Sstevel@tonic-gate		$self->{'buz'} = 42;
148*0Sstevel@tonic-gate		bless $self, $type;
149*0Sstevel@tonic-gate	}
150*0Sstevel@tonic-gate
151*0Sstevel@tonic-gate	package Foo;
152*0Sstevel@tonic-gate	@ISA = qw( Bar );
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gate	sub new {
155*0Sstevel@tonic-gate		my $type = shift;
156*0Sstevel@tonic-gate		my $self = Bar->new;
157*0Sstevel@tonic-gate		$self->{'biz'} = 11;
158*0Sstevel@tonic-gate		bless $self, $type;
159*0Sstevel@tonic-gate	}
160*0Sstevel@tonic-gate
161*0Sstevel@tonic-gate	package main;
162*0Sstevel@tonic-gate
163*0Sstevel@tonic-gate	$a = Foo->new;
164*0Sstevel@tonic-gate	print "buz = ", $a->{'buz'}, "\n";
165*0Sstevel@tonic-gate	print "biz = ", $a->{'biz'}, "\n";
166*0Sstevel@tonic-gate
167*0Sstevel@tonic-gate
168*0Sstevel@tonic-gate
169*0Sstevel@tonic-gate=head1 OBJECT RELATIONSHIPS
170*0Sstevel@tonic-gate
171*0Sstevel@tonic-gateThe following demonstrates how one might implement "containing" and "using"
172*0Sstevel@tonic-gaterelationships between objects.
173*0Sstevel@tonic-gate
174*0Sstevel@tonic-gate	package Bar;
175*0Sstevel@tonic-gate
176*0Sstevel@tonic-gate	sub new {
177*0Sstevel@tonic-gate		my $type = shift;
178*0Sstevel@tonic-gate		my $self = {};
179*0Sstevel@tonic-gate		$self->{'buz'} = 42;
180*0Sstevel@tonic-gate		bless $self, $type;
181*0Sstevel@tonic-gate	}
182*0Sstevel@tonic-gate
183*0Sstevel@tonic-gate	package Foo;
184*0Sstevel@tonic-gate
185*0Sstevel@tonic-gate	sub new {
186*0Sstevel@tonic-gate		my $type = shift;
187*0Sstevel@tonic-gate		my $self = {};
188*0Sstevel@tonic-gate		$self->{'Bar'} = Bar->new;
189*0Sstevel@tonic-gate		$self->{'biz'} = 11;
190*0Sstevel@tonic-gate		bless $self, $type;
191*0Sstevel@tonic-gate	}
192*0Sstevel@tonic-gate
193*0Sstevel@tonic-gate	package main;
194*0Sstevel@tonic-gate
195*0Sstevel@tonic-gate	$a = Foo->new;
196*0Sstevel@tonic-gate	print "buz = ", $a->{'Bar'}->{'buz'}, "\n";
197*0Sstevel@tonic-gate	print "biz = ", $a->{'biz'}, "\n";
198*0Sstevel@tonic-gate
199*0Sstevel@tonic-gate
200*0Sstevel@tonic-gate
201*0Sstevel@tonic-gate=head1 OVERRIDING SUPERCLASS METHODS
202*0Sstevel@tonic-gate
203*0Sstevel@tonic-gateThe following example demonstrates how to override a superclass method and
204*0Sstevel@tonic-gatethen call the overridden method.  The B<SUPER> pseudo-class allows the
205*0Sstevel@tonic-gateprogrammer to call an overridden superclass method without actually knowing
206*0Sstevel@tonic-gatewhere that method is defined.
207*0Sstevel@tonic-gate
208*0Sstevel@tonic-gate	package Buz;
209*0Sstevel@tonic-gate	sub goo { print "here's the goo\n" }
210*0Sstevel@tonic-gate
211*0Sstevel@tonic-gate	package Bar; @ISA = qw( Buz );
212*0Sstevel@tonic-gate	sub google { print "google here\n" }
213*0Sstevel@tonic-gate
214*0Sstevel@tonic-gate	package Baz;
215*0Sstevel@tonic-gate	sub mumble { print "mumbling\n" }
216*0Sstevel@tonic-gate
217*0Sstevel@tonic-gate	package Foo;
218*0Sstevel@tonic-gate	@ISA = qw( Bar Baz );
219*0Sstevel@tonic-gate
220*0Sstevel@tonic-gate	sub new {
221*0Sstevel@tonic-gate		my $type = shift;
222*0Sstevel@tonic-gate		bless [], $type;
223*0Sstevel@tonic-gate	}
224*0Sstevel@tonic-gate	sub grr { print "grumble\n" }
225*0Sstevel@tonic-gate	sub goo {
226*0Sstevel@tonic-gate		my $self = shift;
227*0Sstevel@tonic-gate		$self->SUPER::goo();
228*0Sstevel@tonic-gate	}
229*0Sstevel@tonic-gate	sub mumble {
230*0Sstevel@tonic-gate		my $self = shift;
231*0Sstevel@tonic-gate		$self->SUPER::mumble();
232*0Sstevel@tonic-gate	}
233*0Sstevel@tonic-gate	sub google {
234*0Sstevel@tonic-gate		my $self = shift;
235*0Sstevel@tonic-gate		$self->SUPER::google();
236*0Sstevel@tonic-gate	}
237*0Sstevel@tonic-gate
238*0Sstevel@tonic-gate	package main;
239*0Sstevel@tonic-gate
240*0Sstevel@tonic-gate	$foo = Foo->new;
241*0Sstevel@tonic-gate	$foo->mumble;
242*0Sstevel@tonic-gate	$foo->grr;
243*0Sstevel@tonic-gate	$foo->goo;
244*0Sstevel@tonic-gate	$foo->google;
245*0Sstevel@tonic-gate
246*0Sstevel@tonic-gateNote that C<SUPER> refers to the superclasses of the current package
247*0Sstevel@tonic-gate(C<Foo>), not to the superclasses of C<$self>.
248*0Sstevel@tonic-gate
249*0Sstevel@tonic-gate
250*0Sstevel@tonic-gate=head1 USING RELATIONSHIP WITH SDBM
251*0Sstevel@tonic-gate
252*0Sstevel@tonic-gateThis example demonstrates an interface for the SDBM class.  This creates a
253*0Sstevel@tonic-gate"using" relationship between the SDBM class and the new class Mydbm.
254*0Sstevel@tonic-gate
255*0Sstevel@tonic-gate	package Mydbm;
256*0Sstevel@tonic-gate
257*0Sstevel@tonic-gate	require SDBM_File;
258*0Sstevel@tonic-gate	require Tie::Hash;
259*0Sstevel@tonic-gate	@ISA = qw( Tie::Hash );
260*0Sstevel@tonic-gate
261*0Sstevel@tonic-gate	sub TIEHASH {
262*0Sstevel@tonic-gate	    my $type = shift;
263*0Sstevel@tonic-gate	    my $ref  = SDBM_File->new(@_);
264*0Sstevel@tonic-gate	    bless {'dbm' => $ref}, $type;
265*0Sstevel@tonic-gate	}
266*0Sstevel@tonic-gate	sub FETCH {
267*0Sstevel@tonic-gate	    my $self = shift;
268*0Sstevel@tonic-gate	    my $ref  = $self->{'dbm'};
269*0Sstevel@tonic-gate	    $ref->FETCH(@_);
270*0Sstevel@tonic-gate	}
271*0Sstevel@tonic-gate	sub STORE {
272*0Sstevel@tonic-gate	    my $self = shift;
273*0Sstevel@tonic-gate	    if (defined $_[0]){
274*0Sstevel@tonic-gate		my $ref = $self->{'dbm'};
275*0Sstevel@tonic-gate		$ref->STORE(@_);
276*0Sstevel@tonic-gate	    } else {
277*0Sstevel@tonic-gate		die "Cannot STORE an undefined key in Mydbm\n";
278*0Sstevel@tonic-gate	    }
279*0Sstevel@tonic-gate	}
280*0Sstevel@tonic-gate
281*0Sstevel@tonic-gate	package main;
282*0Sstevel@tonic-gate	use Fcntl qw( O_RDWR O_CREAT );
283*0Sstevel@tonic-gate
284*0Sstevel@tonic-gate	tie %foo, "Mydbm", "Sdbm", O_RDWR|O_CREAT, 0640;
285*0Sstevel@tonic-gate	$foo{'bar'} = 123;
286*0Sstevel@tonic-gate	print "foo-bar = $foo{'bar'}\n";
287*0Sstevel@tonic-gate
288*0Sstevel@tonic-gate	tie %bar, "Mydbm", "Sdbm2", O_RDWR|O_CREAT, 0640;
289*0Sstevel@tonic-gate	$bar{'Cathy'} = 456;
290*0Sstevel@tonic-gate	print "bar-Cathy = $bar{'Cathy'}\n";
291*0Sstevel@tonic-gate
292*0Sstevel@tonic-gate=head1 THINKING OF CODE REUSE
293*0Sstevel@tonic-gate
294*0Sstevel@tonic-gateOne strength of Object-Oriented languages is the ease with which old code
295*0Sstevel@tonic-gatecan use new code.  The following examples will demonstrate first how one can
296*0Sstevel@tonic-gatehinder code reuse and then how one can promote code reuse.
297*0Sstevel@tonic-gate
298*0Sstevel@tonic-gateThis first example illustrates a class which uses a fully-qualified method
299*0Sstevel@tonic-gatecall to access the "private" method BAZ().  The second example will show
300*0Sstevel@tonic-gatethat it is impossible to override the BAZ() method.
301*0Sstevel@tonic-gate
302*0Sstevel@tonic-gate	package FOO;
303*0Sstevel@tonic-gate
304*0Sstevel@tonic-gate	sub new {
305*0Sstevel@tonic-gate		my $type = shift;
306*0Sstevel@tonic-gate		bless {}, $type;
307*0Sstevel@tonic-gate	}
308*0Sstevel@tonic-gate	sub bar {
309*0Sstevel@tonic-gate		my $self = shift;
310*0Sstevel@tonic-gate		$self->FOO::private::BAZ;
311*0Sstevel@tonic-gate	}
312*0Sstevel@tonic-gate
313*0Sstevel@tonic-gate	package FOO::private;
314*0Sstevel@tonic-gate
315*0Sstevel@tonic-gate	sub BAZ {
316*0Sstevel@tonic-gate		print "in BAZ\n";
317*0Sstevel@tonic-gate	}
318*0Sstevel@tonic-gate
319*0Sstevel@tonic-gate	package main;
320*0Sstevel@tonic-gate
321*0Sstevel@tonic-gate	$a = FOO->new;
322*0Sstevel@tonic-gate	$a->bar;
323*0Sstevel@tonic-gate
324*0Sstevel@tonic-gateNow we try to override the BAZ() method.  We would like FOO::bar() to call
325*0Sstevel@tonic-gateGOOP::BAZ(), but this cannot happen because FOO::bar() explicitly calls
326*0Sstevel@tonic-gateFOO::private::BAZ().
327*0Sstevel@tonic-gate
328*0Sstevel@tonic-gate	package FOO;
329*0Sstevel@tonic-gate
330*0Sstevel@tonic-gate	sub new {
331*0Sstevel@tonic-gate		my $type = shift;
332*0Sstevel@tonic-gate		bless {}, $type;
333*0Sstevel@tonic-gate	}
334*0Sstevel@tonic-gate	sub bar {
335*0Sstevel@tonic-gate		my $self = shift;
336*0Sstevel@tonic-gate		$self->FOO::private::BAZ;
337*0Sstevel@tonic-gate	}
338*0Sstevel@tonic-gate
339*0Sstevel@tonic-gate	package FOO::private;
340*0Sstevel@tonic-gate
341*0Sstevel@tonic-gate	sub BAZ {
342*0Sstevel@tonic-gate		print "in BAZ\n";
343*0Sstevel@tonic-gate	}
344*0Sstevel@tonic-gate
345*0Sstevel@tonic-gate	package GOOP;
346*0Sstevel@tonic-gate	@ISA = qw( FOO );
347*0Sstevel@tonic-gate	sub new {
348*0Sstevel@tonic-gate		my $type = shift;
349*0Sstevel@tonic-gate		bless {}, $type;
350*0Sstevel@tonic-gate	}
351*0Sstevel@tonic-gate
352*0Sstevel@tonic-gate	sub BAZ {
353*0Sstevel@tonic-gate		print "in GOOP::BAZ\n";
354*0Sstevel@tonic-gate	}
355*0Sstevel@tonic-gate
356*0Sstevel@tonic-gate	package main;
357*0Sstevel@tonic-gate
358*0Sstevel@tonic-gate	$a = GOOP->new;
359*0Sstevel@tonic-gate	$a->bar;
360*0Sstevel@tonic-gate
361*0Sstevel@tonic-gateTo create reusable code we must modify class FOO, flattening class
362*0Sstevel@tonic-gateFOO::private.  The next example shows a reusable class FOO which allows the
363*0Sstevel@tonic-gatemethod GOOP::BAZ() to be used in place of FOO::BAZ().
364*0Sstevel@tonic-gate
365*0Sstevel@tonic-gate	package FOO;
366*0Sstevel@tonic-gate
367*0Sstevel@tonic-gate	sub new {
368*0Sstevel@tonic-gate		my $type = shift;
369*0Sstevel@tonic-gate		bless {}, $type;
370*0Sstevel@tonic-gate	}
371*0Sstevel@tonic-gate	sub bar {
372*0Sstevel@tonic-gate		my $self = shift;
373*0Sstevel@tonic-gate		$self->BAZ;
374*0Sstevel@tonic-gate	}
375*0Sstevel@tonic-gate
376*0Sstevel@tonic-gate	sub BAZ {
377*0Sstevel@tonic-gate		print "in BAZ\n";
378*0Sstevel@tonic-gate	}
379*0Sstevel@tonic-gate
380*0Sstevel@tonic-gate	package GOOP;
381*0Sstevel@tonic-gate	@ISA = qw( FOO );
382*0Sstevel@tonic-gate
383*0Sstevel@tonic-gate	sub new {
384*0Sstevel@tonic-gate		my $type = shift;
385*0Sstevel@tonic-gate		bless {}, $type;
386*0Sstevel@tonic-gate	}
387*0Sstevel@tonic-gate	sub BAZ {
388*0Sstevel@tonic-gate		print "in GOOP::BAZ\n";
389*0Sstevel@tonic-gate	}
390*0Sstevel@tonic-gate
391*0Sstevel@tonic-gate	package main;
392*0Sstevel@tonic-gate
393*0Sstevel@tonic-gate	$a = GOOP->new;
394*0Sstevel@tonic-gate	$a->bar;
395*0Sstevel@tonic-gate
396*0Sstevel@tonic-gate=head1 CLASS CONTEXT AND THE OBJECT
397*0Sstevel@tonic-gate
398*0Sstevel@tonic-gateUse the object to solve package and class context problems.  Everything a
399*0Sstevel@tonic-gatemethod needs should be available via the object or should be passed as a
400*0Sstevel@tonic-gateparameter to the method.
401*0Sstevel@tonic-gate
402*0Sstevel@tonic-gateA class will sometimes have static or global data to be used by the
403*0Sstevel@tonic-gatemethods.  A subclass may want to override that data and replace it with new
404*0Sstevel@tonic-gatedata.  When this happens the superclass may not know how to find the new
405*0Sstevel@tonic-gatecopy of the data.
406*0Sstevel@tonic-gate
407*0Sstevel@tonic-gateThis problem can be solved by using the object to define the context of the
408*0Sstevel@tonic-gatemethod.  Let the method look in the object for a reference to the data.  The
409*0Sstevel@tonic-gatealternative is to force the method to go hunting for the data ("Is it in my
410*0Sstevel@tonic-gateclass, or in a subclass?  Which subclass?"), and this can be inconvenient
411*0Sstevel@tonic-gateand will lead to hackery.  It is better just to let the object tell the
412*0Sstevel@tonic-gatemethod where that data is located.
413*0Sstevel@tonic-gate
414*0Sstevel@tonic-gate	package Bar;
415*0Sstevel@tonic-gate
416*0Sstevel@tonic-gate	%fizzle = ( 'Password' => 'XYZZY' );
417*0Sstevel@tonic-gate
418*0Sstevel@tonic-gate	sub new {
419*0Sstevel@tonic-gate		my $type = shift;
420*0Sstevel@tonic-gate		my $self = {};
421*0Sstevel@tonic-gate		$self->{'fizzle'} = \%fizzle;
422*0Sstevel@tonic-gate		bless $self, $type;
423*0Sstevel@tonic-gate	}
424*0Sstevel@tonic-gate
425*0Sstevel@tonic-gate	sub enter {
426*0Sstevel@tonic-gate		my $self = shift;
427*0Sstevel@tonic-gate
428*0Sstevel@tonic-gate		# Don't try to guess if we should use %Bar::fizzle
429*0Sstevel@tonic-gate		# or %Foo::fizzle.  The object already knows which
430*0Sstevel@tonic-gate		# we should use, so just ask it.
431*0Sstevel@tonic-gate		#
432*0Sstevel@tonic-gate		my $fizzle = $self->{'fizzle'};
433*0Sstevel@tonic-gate
434*0Sstevel@tonic-gate		print "The word is ", $fizzle->{'Password'}, "\n";
435*0Sstevel@tonic-gate	}
436*0Sstevel@tonic-gate
437*0Sstevel@tonic-gate	package Foo;
438*0Sstevel@tonic-gate	@ISA = qw( Bar );
439*0Sstevel@tonic-gate
440*0Sstevel@tonic-gate	%fizzle = ( 'Password' => 'Rumple' );
441*0Sstevel@tonic-gate
442*0Sstevel@tonic-gate	sub new {
443*0Sstevel@tonic-gate		my $type = shift;
444*0Sstevel@tonic-gate		my $self = Bar->new;
445*0Sstevel@tonic-gate		$self->{'fizzle'} = \%fizzle;
446*0Sstevel@tonic-gate		bless $self, $type;
447*0Sstevel@tonic-gate	}
448*0Sstevel@tonic-gate
449*0Sstevel@tonic-gate	package main;
450*0Sstevel@tonic-gate
451*0Sstevel@tonic-gate	$a = Bar->new;
452*0Sstevel@tonic-gate	$b = Foo->new;
453*0Sstevel@tonic-gate	$a->enter;
454*0Sstevel@tonic-gate	$b->enter;
455*0Sstevel@tonic-gate
456*0Sstevel@tonic-gate=head1 INHERITING A CONSTRUCTOR
457*0Sstevel@tonic-gate
458*0Sstevel@tonic-gateAn inheritable constructor should use the second form of bless() which allows
459*0Sstevel@tonic-gateblessing directly into a specified class.  Notice in this example that the
460*0Sstevel@tonic-gateobject will be a BAR not a FOO, even though the constructor is in class FOO.
461*0Sstevel@tonic-gate
462*0Sstevel@tonic-gate	package FOO;
463*0Sstevel@tonic-gate
464*0Sstevel@tonic-gate	sub new {
465*0Sstevel@tonic-gate		my $type = shift;
466*0Sstevel@tonic-gate		my $self = {};
467*0Sstevel@tonic-gate		bless $self, $type;
468*0Sstevel@tonic-gate	}
469*0Sstevel@tonic-gate
470*0Sstevel@tonic-gate	sub baz {
471*0Sstevel@tonic-gate		print "in FOO::baz()\n";
472*0Sstevel@tonic-gate	}
473*0Sstevel@tonic-gate
474*0Sstevel@tonic-gate	package BAR;
475*0Sstevel@tonic-gate	@ISA = qw(FOO);
476*0Sstevel@tonic-gate
477*0Sstevel@tonic-gate	sub baz {
478*0Sstevel@tonic-gate		print "in BAR::baz()\n";
479*0Sstevel@tonic-gate	}
480*0Sstevel@tonic-gate
481*0Sstevel@tonic-gate	package main;
482*0Sstevel@tonic-gate
483*0Sstevel@tonic-gate	$a = BAR->new;
484*0Sstevel@tonic-gate	$a->baz;
485*0Sstevel@tonic-gate
486*0Sstevel@tonic-gate=head1 DELEGATION
487*0Sstevel@tonic-gate
488*0Sstevel@tonic-gateSome classes, such as SDBM_File, cannot be effectively subclassed because
489*0Sstevel@tonic-gatethey create foreign objects.  Such a class can be extended with some sort of
490*0Sstevel@tonic-gateaggregation technique such as the "using" relationship mentioned earlier or
491*0Sstevel@tonic-gateby delegation.
492*0Sstevel@tonic-gate
493*0Sstevel@tonic-gateThe following example demonstrates delegation using an AUTOLOAD() function to
494*0Sstevel@tonic-gateperform message-forwarding.  This will allow the Mydbm object to behave
495*0Sstevel@tonic-gateexactly like an SDBM_File object.  The Mydbm class could now extend the
496*0Sstevel@tonic-gatebehavior by adding custom FETCH() and STORE() methods, if this is desired.
497*0Sstevel@tonic-gate
498*0Sstevel@tonic-gate	package Mydbm;
499*0Sstevel@tonic-gate
500*0Sstevel@tonic-gate	require SDBM_File;
501*0Sstevel@tonic-gate	require Tie::Hash;
502*0Sstevel@tonic-gate	@ISA = qw(Tie::Hash);
503*0Sstevel@tonic-gate
504*0Sstevel@tonic-gate	sub TIEHASH {
505*0Sstevel@tonic-gate		my $type = shift;
506*0Sstevel@tonic-gate		my $ref = SDBM_File->new(@_);
507*0Sstevel@tonic-gate		bless {'delegate' => $ref};
508*0Sstevel@tonic-gate	}
509*0Sstevel@tonic-gate
510*0Sstevel@tonic-gate	sub AUTOLOAD {
511*0Sstevel@tonic-gate		my $self = shift;
512*0Sstevel@tonic-gate
513*0Sstevel@tonic-gate		# The Perl interpreter places the name of the
514*0Sstevel@tonic-gate		# message in a variable called $AUTOLOAD.
515*0Sstevel@tonic-gate
516*0Sstevel@tonic-gate		# DESTROY messages should never be propagated.
517*0Sstevel@tonic-gate		return if $AUTOLOAD =~ /::DESTROY$/;
518*0Sstevel@tonic-gate
519*0Sstevel@tonic-gate		# Remove the package name.
520*0Sstevel@tonic-gate		$AUTOLOAD =~ s/^Mydbm:://;
521*0Sstevel@tonic-gate
522*0Sstevel@tonic-gate		# Pass the message to the delegate.
523*0Sstevel@tonic-gate		$self->{'delegate'}->$AUTOLOAD(@_);
524*0Sstevel@tonic-gate	}
525*0Sstevel@tonic-gate
526*0Sstevel@tonic-gate	package main;
527*0Sstevel@tonic-gate	use Fcntl qw( O_RDWR O_CREAT );
528*0Sstevel@tonic-gate
529*0Sstevel@tonic-gate	tie %foo, "Mydbm", "adbm", O_RDWR|O_CREAT, 0640;
530*0Sstevel@tonic-gate	$foo{'bar'} = 123;
531*0Sstevel@tonic-gate	print "foo-bar = $foo{'bar'}\n";
532*0Sstevel@tonic-gate
533*0Sstevel@tonic-gate=head1 SEE ALSO
534*0Sstevel@tonic-gate
535*0Sstevel@tonic-gateL<perlboot>, L<perltoot>, L<perltooc>.
536