1asa(3) User Contributed Perl Documentation asa(3)
2
3
4
6 asa - Lets your class/object say it works like something else
7
9 #########################################
10 # Your Code
11
12 package My::WereDuck;
13
14 use base 'My::Lycanthrope';
15 use asa 'Duck';
16
17 sub quack {
18 return "Hi! errr... Quack!";
19 }
20
21 ################################################
22 # Their Code
23
24 sub strangle {
25 my $duck = shift;
26 unless ( $duck->isa('Duck') ) {
27 die "We only strangle ducks";
28 }
29 print "Farmer Joe wrings the duck's neck\n";
30 print "Said the duck, '" . $duck->quack . "'\n";
31 print "We ate well that night.\n";
32 }
33
35 Perl 5 doesn't natively support Java-style interfaces, and it doesn't
36 support Perl 6 style roles either.
37
38 You can get both of these things in half a dozen different ways via
39 various CPAN modules, but they usually require that you buy into "their
40 way" of implementing your code.
41
42 Other have turned to "duck typing".
43
44 This is, for the most part, a fairly naive check that says "can you do
45 this method", under the "if it looks like a duck, and quacks like a
46 duck, then it must be a duck".
47
48 It assumes that if you have a "->quack" method, then they will treat
49 you as a duck, because doing things like adding "Duck" to your @ISA
50 array means you are also forced to take their implementation.
51
52 There is, of course, a better way.
53
54 For better or worse, Perl's "->isa" functionality to determine if
55 something is or is not a particular class/object is defined as a
56 method, not a function, and so that means that as well as adding
57 something to you @ISA array, so that Perl's "UNIVERSAL::isa" method can
58 work with it, you are also allowed to simply overload your own "isa"
59 method and answer directly whether or not you are something.
60
61 The simplest form of the idiom looks like this.
62
63 sub isa {
64 return 1 if $_[1] eq 'Duck';
65 shift->SUPER::isa(@_);
66 }
67
68 This reads "Check my type as normal, but if anyone wants to know if I'm
69 a duck, then tell them yes".
70
71 Now, there are a few people that have argued that this is "lying" about
72 your class, but this argument is based on the idea that @ISA is somehow
73 more "real" than using the method directly.
74
75 It also assumes that what you advertise you implement needs to be in
76 sync with the method resolution for any given function. But in the best
77 and cleanest implementation of code, the API is orthogonal (although
78 most often related) to the implementation.
79
80 And although @ISA is about implementation and API, overloading "isa" to
81 let you change your API is not at all bad when seen in this light.
82
83 What does asa.pm do?
84 Much as base provides convenient syntactic sugar for loading your
85 parent class and setting @ISA, this pragma will provide convenient
86 syntactic sugar for creating your own custom overloaded isa functions.
87
88 Beyond just the idiom above, it implements various workarounds for some
89 edge cases, so you don't have to, and allows clear seperation of
90 concerns.
91
92 You should just be able to use it, and if something ever goes wrong,
93 then it's my fault, and I'll fix it.
94
95 What doesn't asa.pm do?
96 In Perl, highly robust introspection is really hard. Which is why most
97 modules that provide some level of interface functionality require you
98 to explicitly define them in multiple classes, and start to tread on
99 your toes.
100
101 This class does not do any strict enforcement of interfaces. 90% of the
102 time, what you want to do, and the methods you need to implement, are
103 going to be pretty obvious, so it's your fault if you don't provide
104 them.
105
106 But at least this way, you can implement them however you like, and
107 "asa" will just take care of the details of safely telling everyone
108 else you are a duck :)
109
110 What if a Duck method clashes with a My::Package method?
111 Unlike Perl 6, which implements a concept called "multi-methods", Perl
112 5 does not have a native approach to solving the problem of "API
113 collision".
114
115 Originally from the Java/C++ world, the problem of overcoming language
116 API limitations can be done through the use of one of several "design
117 patterns".
118
119 For you, the victim of API collision, you might be interested in the
120 "Adapter" pattern.
121
122 For more information on implementing the Adapter pattern in Perl, see
123 Class::Adapter, which provides a veritable toolkit for creating an
124 implementation of the Adapter pattern which can solve your problem.
125
127 Bugs should be always be reported via the CPAN bug tracker at
128
129 <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=asa>
130
131 For other issues, or commercial enhancement or support, contact the
132 author.
133
135 Adam Kennedy <cpan@ali.as<
136
138 base, <http://ali.as/>
139
141 Copyright (c) 2006 Adam Kennedy. All rights reserved.
142
143 This program is free software; you can redistribute it and/or modify it
144 under the same terms as Perl itself.
145
146 The full text of the license can be found in the LICENSE file included
147 with this module.
148
149
150
151perl v5.12.0 2006-05-10 asa(3)