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