line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
#Time-stamp: "2004-12-29 20:13:16 AST" |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
require 5; |
5
|
|
|
|
|
|
|
package Class::Classless; |
6
|
2
|
|
|
2
|
|
24302
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
109
|
|
7
|
2
|
|
|
2
|
|
10
|
use vars qw($VERSION @ISA $Debug $ROOT %Pretty_form); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
170
|
|
8
|
2
|
|
|
2
|
|
10
|
use Carp; |
|
2
|
|
|
|
|
8
|
|
|
2
|
|
|
|
|
5117
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
$VERSION = "1.35"; |
11
|
|
|
|
|
|
|
@ISA = (); |
12
|
|
|
|
|
|
|
$Debug = 0 unless defined $Debug; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
########################################################################### |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 NAME |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
Class::Classless -- framework for classless OOP |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 SYNOPSIS |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
use strict; |
23
|
|
|
|
|
|
|
use Class::Classless; |
24
|
|
|
|
|
|
|
my $ob1 = $Class::Classless::ROOT->clone; |
25
|
|
|
|
|
|
|
$ob1->{'NAME'} = 'Ob1'; |
26
|
|
|
|
|
|
|
$ob1->{'stuff'} = 123; |
27
|
|
|
|
|
|
|
$ob1->{'Thing'} = 789; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
my $ob2 = $ob1->clone; |
30
|
|
|
|
|
|
|
$ob2->{'NAME'} = 'Ob2'; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
printf "ob1 stuff: <%s>\n", $ob1->{'stuff'}; |
33
|
|
|
|
|
|
|
printf "ob2 stuff: <%s>\n", $ob2->{'stuff'}; |
34
|
|
|
|
|
|
|
printf "ob1 Thing: <%s>\n", $ob1->{'Thing'}; |
35
|
|
|
|
|
|
|
printf "ob2 Thing: <%s>\n", $ob2->{'Thing'}; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
$ob1->{'METHODS'}{'zaz'} = sub { |
38
|
|
|
|
|
|
|
print "Zaz! on ", $_[0]{'NAME'}, "\n"; |
39
|
|
|
|
|
|
|
}; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
$ob1->zaz; |
42
|
|
|
|
|
|
|
$ob2->zaz; |
43
|
|
|
|
|
|
|
$ob1->EXAMINE; |
44
|
|
|
|
|
|
|
$ob2->EXAMINE; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
This prints the following: |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
ob1 stuff: <123> |
49
|
|
|
|
|
|
|
ob2 stuff: <123> |
50
|
|
|
|
|
|
|
ob1 Thing: <789> |
51
|
|
|
|
|
|
|
ob2 Thing: <> |
52
|
|
|
|
|
|
|
Zaz! on Ob1 |
53
|
|
|
|
|
|
|
Zaz! on Ob2 |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
'stuff', 123, |
56
|
|
|
|
|
|
|
'NAME', 'Ob1', |
57
|
|
|
|
|
|
|
'Thing', 789, |
58
|
|
|
|
|
|
|
'METHODS', { 'zaz', 'CODE(0x20068360)' }, |
59
|
|
|
|
|
|
|
'PARENTS', [ 'ROOT' ], |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
'stuff', 123, |
62
|
|
|
|
|
|
|
'NAME', 'Ob2', |
63
|
|
|
|
|
|
|
'METHODS', { }, |
64
|
|
|
|
|
|
|
'PARENTS', [ 'Ob1' ], |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=head1 DESCRIPTION |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
In class-based OOP frameworks, methods are applicable to objects by |
69
|
|
|
|
|
|
|
virtue of objects belonging to classes that either provide those |
70
|
|
|
|
|
|
|
methods, or inherit them from classes that do. |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
In classless OOP frameworks (AKA delegation-and-prototypes |
73
|
|
|
|
|
|
|
frameworks), what methods an object is capable of is basically an |
74
|
|
|
|
|
|
|
attribute of that object. That is, in Perl terms: instead of methods |
75
|
|
|
|
|
|
|
being entries in the symbol table of the package/class the object |
76
|
|
|
|
|
|
|
belongs to, they are entries in a hash table inside the object. |
77
|
|
|
|
|
|
|
Inheritance is implemented not by having classes inheriting from other |
78
|
|
|
|
|
|
|
classes (via ISA lists), but by having objects inherit from other |
79
|
|
|
|
|
|
|
objects (via PARENTS lists). |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
In class-based OOP frameworks, you get new objects by calling |
82
|
|
|
|
|
|
|
constructors. In a classless framework, you get new objects by |
83
|
|
|
|
|
|
|
copying ("cloning") an existing object -- and the new clone becomes a |
84
|
|
|
|
|
|
|
child (inheritor) of the original object. (Where do you get the one |
85
|
|
|
|
|
|
|
original object? The language provides one, which has no parents, and |
86
|
|
|
|
|
|
|
which contains some general purpose methods like "clone".) |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head1 WHAT'S IN AN OBJECT |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
Each classless object is a reference to a hash, containing: |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
* an entry 'PARENTS', which is a reference to a list of this node's |
93
|
|
|
|
|
|
|
parents. (For ROOT, this will be an empty list; for most nodes, there |
94
|
|
|
|
|
|
|
will be just one item in this list; with multiple parents, you get |
95
|
|
|
|
|
|
|
multiple inheritance.) |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
* An entry 'NAME', which is initialized to a unique value (like |
98
|
|
|
|
|
|
|
"x_11") when the object has just been created by cloning. The 'NAME' |
99
|
|
|
|
|
|
|
attribute is not required, and deleting it is harmless. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
* An entry 'METHODS', which is a reference to a hash that maps method |
102
|
|
|
|
|
|
|
names (e.g., "funk") to coderefs or to constant values. When you |
103
|
|
|
|
|
|
|
call $foo->funk(@stuff), Class::Classless's dispatcher looks to see if |
104
|
|
|
|
|
|
|
there's a $foo->{'METHODS'}{'funk'}. If so, and if it's a coderef, then |
105
|
|
|
|
|
|
|
that coderef is called with ($foo, $callstate, @stuff) as its |
106
|
|
|
|
|
|
|
parameter list (See the section "What A Method Sees", below, for |
107
|
|
|
|
|
|
|
an explanation of this). If |
108
|
|
|
|
|
|
|
there's a $foo->{'METHODS'}{'funk'} and it's I a coderef, then the |
109
|
|
|
|
|
|
|
value is returned, possibly with automagical dereferencing. (See the |
110
|
|
|
|
|
|
|
section "Constant Methods", below.) But, finally, if there is no such |
111
|
|
|
|
|
|
|
method, Class::Classless's dispatcher looks in $foo's parent to see |
112
|
|
|
|
|
|
|
if there's a $foo_parent->{'METHODS'}{'funk'}, and so on up the |
113
|
|
|
|
|
|
|
inheritance tree. If no 'funk' method is found in $foo or any of |
114
|
|
|
|
|
|
|
$foo's ancestors, Class::Classless dies with an error to that effect. |
115
|
|
|
|
|
|
|
(But see the section on the NO_FAIL attribute, below.) |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
* Anything else you want to put in the hash. I provide no inherent |
118
|
|
|
|
|
|
|
mechanism for accessing attributes (unlike, say, Self, which can |
119
|
|
|
|
|
|
|
automagically treat method calls as accessors, roughly speaking), so |
120
|
|
|
|
|
|
|
you're down to setting with $a->{'foo'} = VAL, reading with |
121
|
|
|
|
|
|
|
$a->{'foo'}, and possibly testing for the attribute with an |
122
|
|
|
|
|
|
|
exists($a->{'foo'}). (However, do have a look at the C, |
123
|
|
|
|
|
|
|
C, and C methods, below.) |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head2 METHODS IN ROOT |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
ROOT provides various methods you might find helpful: |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
* $thing->clone -- makes a new object based on an existing one. The |
130
|
|
|
|
|
|
|
only way you get to produce new objects is to clone existing ones. |
131
|
|
|
|
|
|
|
Existing objects are either clones of ROOT, or clones of clones of |
132
|
|
|
|
|
|
|
ROOT, and so on. A newly cloned object has a copy of all its parent's |
133
|
|
|
|
|
|
|
attributes whose names don't match /^[A-Z]/s (i.e., that don't begin |
134
|
|
|
|
|
|
|
with a letter between ASCII capital A and ASCII capital Z, inclusive). |
135
|
|
|
|
|
|
|
The new object is then initialized with a per-session-unique name like |
136
|
|
|
|
|
|
|
"x_12"; its PARENT attribute is set to a list containing its one |
137
|
|
|
|
|
|
|
parent; and its 'METHODS' attribute is set to an empty hash. (Note |
138
|
|
|
|
|
|
|
that the copying of parent attributes is B a deep copy -- the |
139
|
|
|
|
|
|
|
parent has foo => [bar, baz], then the child will have a reference to |
140
|
|
|
|
|
|
|
that same list, B a copy of that list!) |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
(Also, if $thing->is_lineage_memoized is true, the clone will have a |
143
|
|
|
|
|
|
|
memoized lineage too. And note that $Class::Classless::ROOT has |
144
|
|
|
|
|
|
|
lineage memoization off. See the description of |
145
|
|
|
|
|
|
|
"$thing->memoize_lineage", below, for a description of what this all |
146
|
|
|
|
|
|
|
means.) |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
* $thing->polyclone($thing2, $thing3...) -- makes a new object based |
149
|
|
|
|
|
|
|
on $thing, $thing2, $thing3, etc. Attributes in $thing overrride |
150
|
|
|
|
|
|
|
those in $thing2, and so on. The PARENTS list will consist of $thing, |
151
|
|
|
|
|
|
|
$thing2, $thing3, etc., in that order. |
152
|
|
|
|
|
|
|
Also, if $thing->is_lineage_memoized is true, the clone will have |
153
|
|
|
|
|
|
|
a memoized lineage too. |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
* $thing->get_i('attrib') -- ("get, with inheritance"). |
156
|
|
|
|
|
|
|
$thing->get_i('foo') returns the value of the 'foo' attribute for |
157
|
|
|
|
|
|
|
$thing. If there is no $thing->{'foo'}, it looks for a 'foo' |
158
|
|
|
|
|
|
|
attribute in each of $thing's ancestors. Returns the first one found. |
159
|
|
|
|
|
|
|
If none are found, returns undef. (But note that undef could result |
160
|
|
|
|
|
|
|
if $thing->{'foo'} or $some_parent->{'foo'} is undef.) |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
* $thing->exists_i('attrib') -- ("exists, with inheritance"). |
163
|
|
|
|
|
|
|
$thing->exists('foo') returns true if either $thing or any of its |
164
|
|
|
|
|
|
|
ancestors contains a 'foo' attribute (as tested with simply |
165
|
|
|
|
|
|
|
exists($node->{'foo'})). Otherwise, returns false. |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
* $thing->put_i('attrib', VALUE) -- ("put, with inheritance"). put_i |
168
|
|
|
|
|
|
|
looks across $thing and its ancestors, and for the first one that |
169
|
|
|
|
|
|
|
contains an 'attrib' attribute, sets its value to VALUE, and then |
170
|
|
|
|
|
|
|
returns VALUE. If neither $thing nor any of its ancestors contain a |
171
|
|
|
|
|
|
|
'attrib' attribute, this will set $thing->{'attrib'} = VALUE and |
172
|
|
|
|
|
|
|
return VALUE, but will warn (via C) if $^W (warnings, usually |
173
|
|
|
|
|
|
|
from giving Perl a C<-w> switch) is true. |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
* $thing->EXAMINE -- prints a somewhat simpleminded dump of the |
176
|
|
|
|
|
|
|
contents of the object. Like a cheapo version of Data::Dumper's |
177
|
|
|
|
|
|
|
Dump() function. |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
* $thing->FLATTEN -- deletes all attributes (and their values) in the |
180
|
|
|
|
|
|
|
object whose names do not match /^[A-Z]/s (i.e., whose names don't |
181
|
|
|
|
|
|
|
begin with a letter between ASCII capital A and ASCII capital Z, |
182
|
|
|
|
|
|
|
inclusive). You can use this if you don't need an object's data, but |
183
|
|
|
|
|
|
|
don't feel bold enough to destroy it, because it may have |
184
|
|
|
|
|
|
|
clone-children that would be orphaned (a bad thing) if this node lost |
185
|
|
|
|
|
|
|
its PARENT attribute, say. |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
* $thing->allcan('baz') -- returns the list (in order) of all 'baz' |
188
|
|
|
|
|
|
|
methods in $thing's ISA tree. This may be an empty list. (Note that |
189
|
|
|
|
|
|
|
the NO_FAIL attribute has no effect on the allcan method.) |
190
|
|
|
|
|
|
|
Note especially that the magic dereferencing magic for constant |
191
|
|
|
|
|
|
|
method values is not triggered. That is, what allcan('baz') returns is |
192
|
|
|
|
|
|
|
simply a list of the values of $x->{'METHODS'}{'baz'} wherever such |
193
|
|
|
|
|
|
|
a METHODS entry exists, for all objects in $thing's inheritance tree. |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
* $thing->howcan('baz') -- just like allcan, but the list returned |
196
|
|
|
|
|
|
|
consists of pairs of values, where each pair consists of 1) the object |
197
|
|
|
|
|
|
|
that provides the 'baz' method, followed by 2) the value it provides |
198
|
|
|
|
|
|
|
for that method. (Remember that that value may be a coderef, or it |
199
|
|
|
|
|
|
|
may be any kind of other reference (which will I be magically |
200
|
|
|
|
|
|
|
resolved as it would have been by the dispatcher -- see the section |
201
|
|
|
|
|
|
|
"Constant Methods", or it may be any nonreference scalar value -- |
202
|
|
|
|
|
|
|
including 0 or undef!) The pairs are in order. You can read this |
203
|
|
|
|
|
|
|
list into a hash that maps from the methods to the method-values, but |
204
|
|
|
|
|
|
|
of course then you lose the ordering. |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
* $thing->can('baz') -- if $thing is capable of the method 'baz', this |
207
|
|
|
|
|
|
|
returns true, otherwise it returns false. Do not try to override the |
208
|
|
|
|
|
|
|
can method. (Note that the NO_FAIL attribute has no effect on the |
209
|
|
|
|
|
|
|
can method.) Note also that this does NOT return the method's value, |
210
|
|
|
|
|
|
|
as it did in the first version of Class::Classless, which (like Perl's |
211
|
|
|
|
|
|
|
normal object system) would return the (coderef) value of the method |
212
|
|
|
|
|
|
|
'baz' for the first object in $thing's tree that provided such a |
213
|
|
|
|
|
|
|
method. |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
That worked then, since all method values under the first version |
216
|
|
|
|
|
|
|
of Class::Classless had to be coderefs (which were, of course, true |
217
|
|
|
|
|
|
|
in a boolean context). However, now that a Class::Classless |
218
|
|
|
|
|
|
|
method have have a constant value that is false, having can() return |
219
|
|
|
|
|
|
|
that value would be indistinguishable from having it return any |
220
|
|
|
|
|
|
|
false value meant as a signal the object incapable of the method. |
221
|
|
|
|
|
|
|
In short, can() simply has to return either true or false now. If |
222
|
|
|
|
|
|
|
you need the value of the methods, use allcan() or howcan(). |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
* $thing->VERSION -- same as $thing->get_i('VERSION'). Note that ROOT |
225
|
|
|
|
|
|
|
has an entry of 'VERSION' => '0.00'. Do not try to override the |
226
|
|
|
|
|
|
|
VERSION method. |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
* $thing->VERSION(version_number) -- dies if $thing->VERSION is |
229
|
|
|
|
|
|
|
less than version_number. Otherwise returns $thing->VERSION. |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
* $thing->isa($thing2) -- returns true if $thing2 is in $thing's ISA |
232
|
|
|
|
|
|
|
tree -- i.e., if it's an ancestor of $thing. (Also returns true if |
233
|
|
|
|
|
|
|
$thing2 B $thing.) Otherwise returns false. Do not try to |
234
|
|
|
|
|
|
|
override the isa method. |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
* $thing->ISA_TREE -- returns $thing's ISA tree, linearized -- i.e., |
237
|
|
|
|
|
|
|
the list of nodes, in order, starting with $thing (and presumably |
238
|
|
|
|
|
|
|
ending with $ROOT), that you would search thru for method calls on |
239
|
|
|
|
|
|
|
$thing, or get_i calls on $thing. Do not try to override the ISA_TREE |
240
|
|
|
|
|
|
|
method. |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
* $thing->memoize_lineage -- makes this object eligible for having its |
243
|
|
|
|
|
|
|
ISA_TREE cached. Normally, every method call on an object causes the |
244
|
|
|
|
|
|
|
routine ISA_TREE to be called, so that Class::Classless knows where to |
245
|
|
|
|
|
|
|
look for methods, and in what order. You can avoid this having to |
246
|
|
|
|
|
|
|
happen each time by causing the results of $thing->ISA_TREE to be |
247
|
|
|
|
|
|
|
memoized (cached); then, subsequent method calls on $thing will just |
248
|
|
|
|
|
|
|
use the cached linearization. This means, however, that you must not |
249
|
|
|
|
|
|
|
change any of $thing's ancestry (who its parents are, or any of its |
250
|
|
|
|
|
|
|
parents' parents, etc.), or the changes will not be noticed. (If you |
251
|
|
|
|
|
|
|
do want to change any such thing, unmemoize the lineage first, as |
252
|
|
|
|
|
|
|
below. Also remember that you will need to unmemoize the lineages of |
253
|
|
|
|
|
|
|
all existing clones, too.) |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
(The ISA_TREE cache happens to be stored in $thing->{'ISA_CACHE'}.) |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
$thing->memoize_lineage has no effect if memoization is already on. |
258
|
|
|
|
|
|
|
This always returns $thing, which makes it convenient for calling on |
259
|
|
|
|
|
|
|
newly cloned objects: |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
$thing = $foo->clone->memoize_lineage; |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
Note that as described above, the normal behavior of $foo->clone is to |
264
|
|
|
|
|
|
|
turn on ISA_TREE memoization for any new clones of $foo if $foo has |
265
|
|
|
|
|
|
|
its ISA_TREE memoization turned on. |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
* $thing->unmemoize_lineage -- this turns off the above-mentioned |
268
|
|
|
|
|
|
|
ISA_TREE cache for $thing. Has no effect if lineage-memoization is |
269
|
|
|
|
|
|
|
already off. Like $thing->memoize_lineage, this returns $thing. |
270
|
|
|
|
|
|
|
Think carefully about how you use this. It's never going to be a |
271
|
|
|
|
|
|
|
problem if the only way you call it is as: |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
$thing = $foo->clone->unmemoize_lineage; |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
I.e., when you want a new object whose lineage you want to be |
276
|
|
|
|
|
|
|
free to alter later without having to worry about caching. |
277
|
|
|
|
|
|
|
(And when in doubt, leave caching off.) |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
However, note that this is wrong: |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
$thing = $foo->clone->memoize_lineage; |
282
|
|
|
|
|
|
|
...stuff... |
283
|
|
|
|
|
|
|
push @{$thing->{'PARENTS'}}, $yorp; |
284
|
|
|
|
|
|
|
$thing->unmemoize_lineage; |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
...because the 'unmemoize_lineage' call on $thing will be using an |
287
|
|
|
|
|
|
|
already out-of-date cache of its old ISA_TREE. That is likely to be |
288
|
|
|
|
|
|
|
harmless, though, unless $yorp overrides the normal |
289
|
|
|
|
|
|
|
'unmemoize_lineage' method. But this is better: |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
$thing = $foo->clone->memoize_lineage; |
292
|
|
|
|
|
|
|
...stuff... |
293
|
|
|
|
|
|
|
$thing->unmemoize_lineage; |
294
|
|
|
|
|
|
|
push @{$thing->{'PARENTS'}}, $yorp; |
295
|
|
|
|
|
|
|
$thing->memoize_lineage; |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
But consider this harder case: |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
$thing = $foo->clone->memoize_lineage; |
300
|
|
|
|
|
|
|
...stuff... |
301
|
|
|
|
|
|
|
$zaz = $thing->clone; # so it will have memoization |
302
|
|
|
|
|
|
|
...more stuff... |
303
|
|
|
|
|
|
|
$thing->unmemoize_lineage; |
304
|
|
|
|
|
|
|
push @{$thing->{'PARENTS'}}, $yorp; |
305
|
|
|
|
|
|
|
$thing->memoize_lineage; |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
Even though you correctly turned off $thing's cache at the right |
308
|
|
|
|
|
|
|
moment, you forgot about $zaz's cache, which was and still is out of |
309
|
|
|
|
|
|
|
date. |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
* $thing->is_lineage_memoized -- returns true iff $thing is using |
312
|
|
|
|
|
|
|
lineage memoization. |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
* $thing->DESTROY -- this is here to trap DESTROY calls that Perl |
315
|
|
|
|
|
|
|
makes when it's about to deallocate an object, either when the |
316
|
|
|
|
|
|
|
object's reference count goes to 0, or at global destruction time. |
317
|
|
|
|
|
|
|
Currently it's a no-op, for many annoyingly complicated reasons. Do |
318
|
|
|
|
|
|
|
I try to override the DESTROY method! If you don't know what |
319
|
|
|
|
|
|
|
DESTROY methods are for anyway, don't worry about it. |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=head1 CONSTANT METHODS |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
I expect that most methods (i.e., things in the $foo->{'METHODS'} |
324
|
|
|
|
|
|
|
hash) will be coderefs. However, if you want the value of a method |
325
|
|
|
|
|
|
|
to be a constant, I figure there's no point in making you say: |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
$foo->{'METHODS'}{'funk'} = sub { 7 }; |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
just so $foo->funk can return the constant value 7. |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
So instead, I've made it so that when you call $foo->funk, and |
332
|
|
|
|
|
|
|
Class::Classless finds that $foo->{'METHODS'}{'funk'} exists, |
333
|
|
|
|
|
|
|
or that $some_ancestor->{'METHODS'}{'funk'} exists, it takes that |
334
|
|
|
|
|
|
|
value and decides what to do with that value, like so: |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
* Unless that value (which, by the way, is free to be undef!) is a |
337
|
|
|
|
|
|
|
reference, then it's a constant, so return it. That means that if you |
338
|
|
|
|
|
|
|
set $foo->{'METHODS'}{'funk'} = 7, then $foo->funk will always return |
339
|
|
|
|
|
|
|
7. |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
* If it's an unblessed coderef, call it with arguments as explained |
342
|
|
|
|
|
|
|
in the "What a Method Sees" section, below. Note that I |
343
|
|
|
|
|
|
|
coderefs (as rare at they are) are I called. |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
* Otherwise, it must be some sort other sort of constant to return, |
346
|
|
|
|
|
|
|
which happens to be a reference. |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
* If it's a reference of the class '_deref_array', then it's |
349
|
|
|
|
|
|
|
array-dereferenced before being returned. So if you wanted |
350
|
|
|
|
|
|
|
$foo->band_members to return a constant list ('Ad Rock', 'MCA', 'Mike |
351
|
|
|
|
|
|
|
D'), you can do it with: $foo->{'METHODS'}{'band_members'} = bless [ |
352
|
|
|
|
|
|
|
'Ad Rock', 'MCA', 'Mike D'], '_deref_array'. When you call |
353
|
|
|
|
|
|
|
$foo->band_members then, Class::Classless's dispatcher will |
354
|
|
|
|
|
|
|
basically say: |
355
|
|
|
|
|
|
|
return(@{$foo->{'METHODS'}{'band_members'}}); |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
* If it's a reference of the class '_deref_scalar', then it's |
358
|
|
|
|
|
|
|
scalar-dereferenced before being returned. This is not as |
359
|
|
|
|
|
|
|
immediately and obviously useful as the same trick with |
360
|
|
|
|
|
|
|
'_deref_array', but it does make possible a few tricks. First off, |
361
|
|
|
|
|
|
|
you can have something like: |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
my $counter = 0; |
364
|
|
|
|
|
|
|
bless $counter, '_deref_scalar'; |
365
|
|
|
|
|
|
|
$fee->{'METHODS'}{'counter_value'} = \$counter; |
366
|
|
|
|
|
|
|
$fye->{'METHODS'}{'counter_value'} = \$counter; |
367
|
|
|
|
|
|
|
$foe->{'METHODS'}{'counter_value'} = \$counter; |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
to have these all share the same value, which you'd get from going |
370
|
|
|
|
|
|
|
$fee->counter_value, $fye->counter_value, or $foe->counter_value. |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
Second off, suppose (as unlikely as it is) you actually wanted a |
373
|
|
|
|
|
|
|
I value to be returned -- but the value you want returned |
374
|
|
|
|
|
|
|
is an unblessed coderef! If you just stuck that value in |
375
|
|
|
|
|
|
|
$foo->{'METHODS'}, it'd get called instead of returned as a constant. |
376
|
|
|
|
|
|
|
Well, you can just go: |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
my $cr = sub { ...whatever... }; |
379
|
|
|
|
|
|
|
$foo->{'METHODS'}{'zaz'} = bless \$cr, '_deref_scalar'; |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
So when you call $foo->zaz, Class::Classless sees a scalar of class |
382
|
|
|
|
|
|
|
'_deref_scalar', and returns it, like |
383
|
|
|
|
|
|
|
return(${$foo->{'METHODS'}{'zaz'}}). That value is, of course, your |
384
|
|
|
|
|
|
|
coderef. |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
* And finally, if the value in $foo->{'METHODS'}{'funk'} was a |
387
|
|
|
|
|
|
|
reference, but was neither an unblessed coderef, nor a reference of |
388
|
|
|
|
|
|
|
class '_deref_array', nor of class '_deref_scalar', then it's just |
389
|
|
|
|
|
|
|
returned. |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
=head1 WHAT A METHOD SEES |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
Under Perl's I object system, when you call |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
$foo->bar($x, @y ...) |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
C's C<@_> will consist of |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
($foo, $x, @y ...) |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
So normally the first thing C will do is something like: |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
my($obj, $first, @rest) = @_; |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
or |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
my $obj = shift @_; |
408
|
|
|
|
|
|
|
my $first = shift @_; |
409
|
|
|
|
|
|
|
my @rest = @_; |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
I, subs called as methods by Class::Classless's dispatcher |
412
|
|
|
|
|
|
|
have one extra argument; $_[1] is the "callstate", an object created |
413
|
|
|
|
|
|
|
every time you call a Class::Classless object, and belonging to the class |
414
|
|
|
|
|
|
|
'Class::Classless::CALLSTATE'. Normally all you'd ever want to do |
415
|
|
|
|
|
|
|
with it is say: |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
$callstate->NEXT('foo', $bar, @baz) |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
which is equivalent to $callstate->SUPER::foo($bar, @baz) under Perl's |
420
|
|
|
|
|
|
|
normal object system. See the section "More on NEXT". |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
So, in other words, the first line of a Class::Classless method to be |
423
|
|
|
|
|
|
|
called as |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
$foo->bar($x, @y ...) |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
would be |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
my($obj, $callstate, $first, @rest) = @_; |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
or the like. |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=head1 SHARED DATA |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
I considered making some sort of mechanism for having private |
436
|
|
|
|
|
|
|
attributes versus inherited attributes, but decided on just letting |
437
|
|
|
|
|
|
|
the user work it out with C, C, and C; onto |
438
|
|
|
|
|
|
|
this I added the feature that attributes whose names start |
439
|
|
|
|
|
|
|
with a character in the ASCII range C<[A-Z]> (as opposed to C<[a-z]>, |
440
|
|
|
|
|
|
|
or anything else) don't get copied by the C method, and also |
441
|
|
|
|
|
|
|
aren't deleted by the C method. That's the |
442
|
|
|
|
|
|
|
I of the special treatment that Class::Classless |
443
|
|
|
|
|
|
|
accords to attributes whose names start with C<[A-Z]>. |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
The upshot of this is that you can have something like "class |
446
|
|
|
|
|
|
|
data" by just taking a generic object (i.e., one you expect |
447
|
|
|
|
|
|
|
to be cloned) and setting attributes in it like |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
$generic->{'Interface'} = 'Tk'; |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
then all clones of that attribute can effectively 'share' that value |
452
|
|
|
|
|
|
|
like so... |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
# send in the clones... |
455
|
|
|
|
|
|
|
$w1 = $generic->clone; |
456
|
|
|
|
|
|
|
$w2 = $generic->clone; |
457
|
|
|
|
|
|
|
$w3 = $generic->clone; |
458
|
|
|
|
|
|
|
...etc... |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
print $w1->get_i('Interface'); # to read it |
461
|
|
|
|
|
|
|
print $w2->get_i('Interface'); # to read it (same value) |
462
|
|
|
|
|
|
|
print $w3->get_i('Interface'); # to read it (same value) |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
print $w2->put_i('Interface', 'VT320'); # to set it |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
and even this, if this makes any useful sense: |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
print $whatever->exists_i('Interface'); # to make sure it exists |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
However, to repeat myself somewhat, the only reason this is shared is |
471
|
|
|
|
|
|
|
that C didn't copy the 'Interface' method when it made clones |
472
|
|
|
|
|
|
|
of $generic, so calling C on any of the children so produced |
473
|
|
|
|
|
|
|
will find the attribute not in the children, but will fall back on |
474
|
|
|
|
|
|
|
finding it in $generic->{'Interface'}. |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
But if you go and set $w1->{'Interface'} (as opposed to using |
477
|
|
|
|
|
|
|
C), then $w1->get_i('Interface') will get you the value of |
478
|
|
|
|
|
|
|
$w1->{'Interface'}, not the value of $generic->{'Interface'}. In other |
479
|
|
|
|
|
|
|
words, you'd be overriding the value you'd still be getting at with |
480
|
|
|
|
|
|
|
$generic->{'Interface'}, $w2->get_i('Interface'), |
481
|
|
|
|
|
|
|
$w3->get_i('Interface'), or even (uninterestingly) |
482
|
|
|
|
|
|
|
$generic->get_i('Interface'). |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
And in any case, you can really share data by virtue of the fact that |
485
|
|
|
|
|
|
|
the clone method (at least, not the default clone method) doesn't do |
486
|
|
|
|
|
|
|
copying of references (AKA "deep copying") -- so you can just have all |
487
|
|
|
|
|
|
|
the objects that you want to share data simply have a reference to a |
488
|
|
|
|
|
|
|
common piece of data: |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
my $bar = 123; |
491
|
|
|
|
|
|
|
$w->{'foo'} = \$bar; |
492
|
|
|
|
|
|
|
# Then any clones of $w will have a reference to that value -- |
493
|
|
|
|
|
|
|
# not to copies of it! |
494
|
|
|
|
|
|
|
# Similarly: |
495
|
|
|
|
|
|
|
$w->{'zaz'} = [5,6,7]; |
496
|
|
|
|
|
|
|
$w->{'quux'} = {a => 11, b => 12}; |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=head1 INHERITANCE SYSTEM |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
If all you want is single-inheritance, you can skip this section, |
502
|
|
|
|
|
|
|
since things will work as you expect: objects inherit from their |
503
|
|
|
|
|
|
|
parents, and so on, all the way back to a parentless object (i.e., |
504
|
|
|
|
|
|
|
ROOT). |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
As to how this works with multiple inheritance, consider first how |
507
|
|
|
|
|
|
|
Perl's built-in mechanism for class inheritance works: first, a |
508
|
|
|
|
|
|
|
depth-first search of the ISA tree, and then falling back to the class |
509
|
|
|
|
|
|
|
UNIVERSAL, which is the implicit root for all classes. |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
Class::Classless's system is different -- consider this case: |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
ROOT/UNIVERSAL |
514
|
|
|
|
|
|
|
| |
515
|
|
|
|
|
|
|
Y |
516
|
|
|
|
|
|
|
/ \ |
517
|
|
|
|
|
|
|
A X |
518
|
|
|
|
|
|
|
| / |
519
|
|
|
|
|
|
|
B / |
520
|
|
|
|
|
|
|
\ / |
521
|
|
|
|
|
|
|
C |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
Here, Perl's depth-first search would linearize the tree (i.e., |
524
|
|
|
|
|
|
|
convert it to a flat list consisting of search path) as: |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
C B A Y X Root/Universal |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
However, I think this is just not the right way to do things. The |
529
|
|
|
|
|
|
|
point of X being a child of Y is so that X can have a chance to |
530
|
|
|
|
|
|
|
override Y. Perl's normal depth-first search doesn't allow that in |
531
|
|
|
|
|
|
|
cases like this. So my rule is: search over ancestors depth-first, |
532
|
|
|
|
|
|
|
but never search a node until you've searched all its children (that |
533
|
|
|
|
|
|
|
is, children that are still ancestors of the node you've built this |
534
|
|
|
|
|
|
|
tree for -- any other children are irrelevant). So I linearize that |
535
|
|
|
|
|
|
|
list as: |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
C B A X Y Root/Universal |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
So X does override Y. (And Root/Universal is not a special case in |
540
|
|
|
|
|
|
|
the searching rule.) |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
Now, fatal errors B result with bizarre trees -- namely ones with |
543
|
|
|
|
|
|
|
cyclicity in them, such as: X's parents are A and B, A's parent is B, |
544
|
|
|
|
|
|
|
and B's parent is A. But in some cases Class::Classless B just |
545
|
|
|
|
|
|
|
try to ignore the cyclic part. So just don't make any cyclic trees, |
546
|
|
|
|
|
|
|
OK? |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
=head1 THE NO_FAIL ATTRIBUTE |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
If you call $thing->zaz and there is no 'zaz' method that $thing is |
551
|
|
|
|
|
|
|
capable of, then normally Class::Classless with throw a fatal error. |
552
|
|
|
|
|
|
|
However, if $thing->get_i{'NO_FAIL'} is true, then a no-operation |
553
|
|
|
|
|
|
|
(like sub { return; } ) simply results. |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
(NO_FAIL also controls what happens if you call $thing->NEXT('zaz') |
556
|
|
|
|
|
|
|
and there is no NEXT 'zaz' method; if NO_FAIL is true, a no-operation |
557
|
|
|
|
|
|
|
results; otherwise, a fatal error results. See the section |
558
|
|
|
|
|
|
|
"More on NEXT", below.) |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
Implementationally, the way this is implemented is that when you call |
561
|
|
|
|
|
|
|
a method, a routine of Class::Classless's called the dispatcher looks |
562
|
|
|
|
|
|
|
figures out the linearization of the inheritance tree of the target |
563
|
|
|
|
|
|
|
object of the method call, and then, one-at-a-time, goes over the |
564
|
|
|
|
|
|
|
objects in the linearization, looking for an object whose METHODS |
565
|
|
|
|
|
|
|
hash contains an entry for the name of the method. ("Linearization" |
566
|
|
|
|
|
|
|
meaning simply a list of objects, in the order in which they should |
567
|
|
|
|
|
|
|
be searched.) |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
Each call also creates an object, called a "callstate" object, one of |
570
|
|
|
|
|
|
|
whose attributes is called "no_fail" (note lowercase), and whose |
571
|
|
|
|
|
|
|
value starts out being undef. If the dispatcher, while going thru |
572
|
|
|
|
|
|
|
the linearization and looking at the METHODS, sees an object with a |
573
|
|
|
|
|
|
|
defined 'NO_FAIL' attribute (note uppercase), it uses that value |
574
|
|
|
|
|
|
|
(the value of the first object in the list with a defined NO_FAIL |
575
|
|
|
|
|
|
|
attribute) to set the no_fail attribute of the callstate. If it |
576
|
|
|
|
|
|
|
finishes searching the list and hasn't seen an object with a METHODS |
577
|
|
|
|
|
|
|
entry for the method it's dispatching for, one of two things will happen: |
578
|
|
|
|
|
|
|
if no_fail is set to true, the dispatcher will act as if it found |
579
|
|
|
|
|
|
|
the method and its value was sub{return}. Otherwise, the dispatcher |
580
|
|
|
|
|
|
|
will die with a fatal error like: |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
Can't find method foo in OBJECT_NAME or any ancestors |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
So, normally, the only way for the no_fail attribute of the callstate |
585
|
|
|
|
|
|
|
to be usefully set is for the dispatcher to have seen an object with |
586
|
|
|
|
|
|
|
a NO_FAIL attribute set. In other words, if you want method lookup |
587
|
|
|
|
|
|
|
in an object to be unfailing, set $x->{'NO_FAIL'} = 1 for it or |
588
|
|
|
|
|
|
|
any of its ancestors; and if you want to override B for a |
589
|
|
|
|
|
|
|
descendant, set its $y->{'NO_FAIL'} = 0. |
590
|
|
|
|
|
|
|
(Note that just for sake of sanity, the NO_FAIL of $ROOT is set to 0.) |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
But in the case of using callstate->NEXT call to continue a method |
593
|
|
|
|
|
|
|
dispatch (i.e., getting the dispatcher to pick up where it left off), |
594
|
|
|
|
|
|
|
you may want to control the callstate's no_fail attribute directly, |
595
|
|
|
|
|
|
|
regardless of the NO_FAIL attributes of any of the objects the |
596
|
|
|
|
|
|
|
dispatcher's seen so far. In that case, you can use the |
597
|
|
|
|
|
|
|
$callstate->set_no_fail_true to set no_fail to true (i.e., lookup |
598
|
|
|
|
|
|
|
failures from NEXTing off of this callstate don't generate fatal |
599
|
|
|
|
|
|
|
errors). See the section on callstates, below, for more options. |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
=head1 CALLSTATES |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
Every time you call a method on a Class::Classless object (whether |
604
|
|
|
|
|
|
|
normally, or via a $callstate->NEXT(...) call), a new |
605
|
|
|
|
|
|
|
Class::Classless::CALLSTATE object is created, and passed as $_[1] to |
606
|
|
|
|
|
|
|
that method. Besides this being the way I happen to implement |
607
|
|
|
|
|
|
|
$callstate->NEXT(I, I) (by recording the state |
608
|
|
|
|
|
|
|
of the dispatcher for later resumption), you can use this object to |
609
|
|
|
|
|
|
|
get metainformation about this method call. You can access that |
610
|
|
|
|
|
|
|
information like so: |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
* $callstate->target -- the object that was the target of the method |
613
|
|
|
|
|
|
|
call. Same as the $_[0] that the method sees. |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
* $callstate->found_name -- the name this method was called as. |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
* $callstate->lineage -- the list of objects representing the |
618
|
|
|
|
|
|
|
linearization of the target object's ISA tree. (Same as |
619
|
|
|
|
|
|
|
$obj->ISA_TREE.) |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
* $callstate->home -- the object the called method was found in. |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
* $callstate->sub_found -- the routine that is being called. |
624
|
|
|
|
|
|
|
Same as $callstate->home->{'METHODS'}{$callstate->target}. |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
* $callstate->found_depth -- the number representing the index in the |
627
|
|
|
|
|
|
|
$callstate->lineage list where this method was found. In other words, |
628
|
|
|
|
|
|
|
$callstate->home is ($callstate->lineage)[$callstate->found_depth]. |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
* $callstate->set_no_fail_true -- set the no_fail attribute of this |
631
|
|
|
|
|
|
|
callstate to true -- meaning failure is impossible for any NEXT calls |
632
|
|
|
|
|
|
|
based on this call. (Obviously it's meaningless to consider failure |
633
|
|
|
|
|
|
|
of the current method -- it was already found, otherwise how could |
634
|
|
|
|
|
|
|
there be code that's accessing its callstate!) I expect this is |
635
|
|
|
|
|
|
|
useful for cases where you want to NEXT, but aren't sure that there |
636
|
|
|
|
|
|
|
is a next method in the tree. With the no_fail set, failure in the |
637
|
|
|
|
|
|
|
NEXT lookup will act as if it triggered a method consisting of just |
638
|
|
|
|
|
|
|
sub { return; }. |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
* $callstate->set_no_fail_false -- set the no_fail attribute of this |
641
|
|
|
|
|
|
|
callstate to true -- meaning failure is possible for any NEXT calls |
642
|
|
|
|
|
|
|
in the contituation of the current call state. I don't anticipate |
643
|
|
|
|
|
|
|
this being useful, but I provide it for completeness. |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
* $callstate->set_no_fail_undef -- set the no_fail attribute of this |
646
|
|
|
|
|
|
|
callstate to undef -- meaning that failure is possible, but that this |
647
|
|
|
|
|
|
|
value can be set by the next object in the linearization of the |
648
|
|
|
|
|
|
|
inheritance tree. I don't anticipate this being useful, but I |
649
|
|
|
|
|
|
|
provide it for completeness. |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
* $callstate->no_fail -- returns the value of no_fail attribute of |
652
|
|
|
|
|
|
|
this callstate so far. See the section "The NO_FAIL attribute", |
653
|
|
|
|
|
|
|
above. I don't anticipate this being useful, but I provide it for |
654
|
|
|
|
|
|
|
completeness. |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
* $callstate->via_next -- return true the current method was |
657
|
|
|
|
|
|
|
called via $callstate->NEXT. Otherwise returns false. |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
The whole callstate mechanism (used by the above methods as well as by |
660
|
|
|
|
|
|
|
the NEXT method) assumes you don't change the object's ISA tree (or |
661
|
|
|
|
|
|
|
any of the METHODS hashes in any part of the ISA tree) in the middle |
662
|
|
|
|
|
|
|
of the call. If you do, the information in $callstate will be out of |
663
|
|
|
|
|
|
|
synch with reality (since it contains the linearization as of the |
664
|
|
|
|
|
|
|
B of the call)), which is fine as long as you don't use it |
665
|
|
|
|
|
|
|
for anything (like NEXTing) after that point, in that call. |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
=head1 MORE ON NEXT |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
Calling $callstate->NEXT is the mechanism I allow for doing what |
670
|
|
|
|
|
|
|
Perl's built-in object system does with SUPER:: calls, and like what |
671
|
|
|
|
|
|
|
some object systems do with "before- and after-demons". |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
The basic syntax to NEXT is as follows: |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
$callstate->NEXT( method_name , ...arguments... ); |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
However, if you call it with a method_name of undef, it will |
678
|
|
|
|
|
|
|
use the current value of $callstate->found_name, i.e., the name |
679
|
|
|
|
|
|
|
the currently running method was found as. Note that this |
680
|
|
|
|
|
|
|
can come to de undefined in two ways -- either by the parameter |
681
|
|
|
|
|
|
|
list being null, as in either of: |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
$callstate->NEXT; |
684
|
|
|
|
|
|
|
...AKA... |
685
|
|
|
|
|
|
|
$callstate->NEXT(); |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
or by being explicitly undef: |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
$callstate->NEXT(undef, $foo, $bar); |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
In either case, the undef is interpreted as $callstate->found_name. |
692
|
|
|
|
|
|
|
I offer this as just a (hopefully) convenient shortcut. |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
Now, if you call NEXT and there is no method with the desired |
695
|
|
|
|
|
|
|
name in the remainder of the linearization of the inheritance tree, |
696
|
|
|
|
|
|
|
what happens depends on the no_fail attribute; if you want to |
697
|
|
|
|
|
|
|
insure that the NEXT will not fail (since failing would mean a |
698
|
|
|
|
|
|
|
fatal error), you can set the callstate's no_fail attribute to true: |
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
$callstate->set_no_fail_true |
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
(which means it can't fail.) |
703
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
Note, by the way, that NEXTing never automatically copies the |
705
|
|
|
|
|
|
|
argument list of the current method for the next one. You have to do |
706
|
|
|
|
|
|
|
that yourself. There's many ways to do it, but consider something |
707
|
|
|
|
|
|
|
like: |
708
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
$x->{"METHODS"}{"foo"} = sub { |
710
|
|
|
|
|
|
|
my($o, $cs) = splice(@_,0,2); |
711
|
|
|
|
|
|
|
# then copy arguments from @_, but don't change @_ any further: |
712
|
|
|
|
|
|
|
my($zaz, @foo) = @_ |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
...stuff... |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
# then you can pass on the arguments still in @_ |
717
|
|
|
|
|
|
|
$cs->NEXT(undef,@_); |
718
|
|
|
|
|
|
|
# undef to mean 'the name I was called as' |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
...stuff... |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
}; |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
If you forgot and just said $cs->NEXT() or (pointlessly) $cs->NEXT(undef), |
725
|
|
|
|
|
|
|
then the next 'foo' method would have nothing in its argument list after |
726
|
|
|
|
|
|
|
its usual two first items (the target object and the callstate). |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
A further note: currently, each method call (whether normal, or via a |
729
|
|
|
|
|
|
|
NEXT) creates a new callstate object. However, when NEXTing, the |
730
|
|
|
|
|
|
|
attributes of the current callstate object are copied into the new |
731
|
|
|
|
|
|
|
callstate object -- except for the via_next attribute, which is forced |
732
|
|
|
|
|
|
|
to true, of course. |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
=head1 BASIC IMPLEMENTATION STRATEGY |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
This module does what it does by blessing all "Class::Classless" |
737
|
|
|
|
|
|
|
objects into a class (Class::Classless::X, in point of fact) |
738
|
|
|
|
|
|
|
that provides no methods except for an AUTOLOAD |
739
|
|
|
|
|
|
|
method that intercepts all method calls and does the dispatching. |
740
|
|
|
|
|
|
|
This is how I fiendishly usurp Perl's normal method dispatching |
741
|
|
|
|
|
|
|
scheme. (Actually I do provide other methods upfront: C, |
742
|
|
|
|
|
|
|
C, C, C, and C, as I basically |
743
|
|
|
|
|
|
|
have to, it turns out.) |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
Consult the source for details. It's not that long. |
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
=head1 CAVEATS AND MUSINGS |
748
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
* The moral of this module is that if you don't like the object |
750
|
|
|
|
|
|
|
framework that comes with a language, quit your bitching and just |
751
|
|
|
|
|
|
|
make your own! And the meta-moral is that object systems aren't |
752
|
|
|
|
|
|
|
black boxes that have to be fused with the language itself. |
753
|
|
|
|
|
|
|
|
754
|
|
|
|
|
|
|
* Note that the C you may export from UNIVERSAL has nothing |
755
|
|
|
|
|
|
|
at all to do with the C that you should be using for |
756
|
|
|
|
|
|
|
Class::Classless objects. The only way you should call C |
757
|
|
|
|
|
|
|
on classless objects is like $obj->can('foo'). |
758
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
* How to test if something is a classless object: |
760
|
|
|
|
|
|
|
C[ ] |
761
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
* Don't make cyclic trees. I don't go to extreme lengths to stop |
763
|
|
|
|
|
|
|
you from doing so, but don't expect sane behavior if you do. |
764
|
|
|
|
|
|
|
|
765
|
|
|
|
|
|
|
* The reason the $callstate->NEXT('foo') is called NEXT is because it |
766
|
|
|
|
|
|
|
starts looking in the I object in the linearization of the |
767
|
|
|
|
|
|
|
ISA_TREE. This next object is not necessarily an ancestor (i.e., a |
768
|
|
|
|
|
|
|
Iior object) of the current object -- in the above section, |
769
|
|
|
|
|
|
|
X is A's next node, altho A is clearly not a superior node. |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
* Don't try to derive new I from any of the classes that |
772
|
|
|
|
|
|
|
Class::Classless defines. First off, it may not work, for any |
773
|
|
|
|
|
|
|
reading of "work". Second off, what's the point? |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
* Note that there's currently no mechanism for parent objects to know |
776
|
|
|
|
|
|
|
what their children are. However, if you needed this, you could |
777
|
|
|
|
|
|
|
override the clone method with something that would track this. But |
778
|
|
|
|
|
|
|
note that this would create circular data structures, complicating |
779
|
|
|
|
|
|
|
garbage collection -- you'd have to explicitly destroy objects, the |
780
|
|
|
|
|
|
|
way you have to with Tree::DAG_Node nodes. |
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
* Why don't I let objects define their own DESTROY methods? One short |
783
|
|
|
|
|
|
|
reason: this unpredictably and intermittently triggers a strange bug |
784
|
|
|
|
|
|
|
in Perl's garbage collection system during global destruction. |
785
|
|
|
|
|
|
|
Better, longer reason: I don't see any way to make sure that, during |
786
|
|
|
|
|
|
|
global destruction, Perl never destroys a parent before its children. |
787
|
|
|
|
|
|
|
If a parent is destroyed before its children, and that parent provides |
788
|
|
|
|
|
|
|
a DESTROY that the children inherit, then when it comes time for the |
789
|
|
|
|
|
|
|
children to be destroyed, the DESTROY method they planned on using |
790
|
|
|
|
|
|
|
would have become inaccessible. This seems an intractable problem. |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
* Callstate objects were added as an afterthought. They are meant to |
793
|
|
|
|
|
|
|
be small and inexpensive, not extensible. I can't imagine a use for |
794
|
|
|
|
|
|
|
them other than the uses outlined in the documentation -- i.e., |
795
|
|
|
|
|
|
|
getting at (or sometimes modifying) an attribute of the current state |
796
|
|
|
|
|
|
|
of the method dispatcher. If you're considering any other use of |
797
|
|
|
|
|
|
|
callstate objects, email me -- I'd be interested in hearing what you |
798
|
|
|
|
|
|
|
have in mind. |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
* While I was writing Class::Classless, I read up on Self. To quote |
801
|
|
|
|
|
|
|
FOLDOC (C), |
802
|
|
|
|
|
|
|
Self is/was "a small, dynamically typed object-oriented language, |
803
|
|
|
|
|
|
|
based purely on prototypes and delegation. Self was developed by the |
804
|
|
|
|
|
|
|
Self Group at Sun Microsystems Laboratories, Inc. and Stanford |
805
|
|
|
|
|
|
|
University. It is an experimental exploratory programming language." |
806
|
|
|
|
|
|
|
For more information, see C |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
=head1 YOU KNOW WHAT THEY SAY... |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
To Marx, a classless society never meant the absolute equality of |
811
|
|
|
|
|
|
|
result, but merely the absence of artificial barriers between social |
812
|
|
|
|
|
|
|
groups. According to David McClellan, a Marx scholar, Marx "had a |
813
|
|
|
|
|
|
|
dynamic or subjective element in his definition of class; a class only |
814
|
|
|
|
|
|
|
existed when it was conscious of itself as such, and this always |
815
|
|
|
|
|
|
|
implied common hostility to another social group." In I
|
816
|
|
|
|
|
|
|
Karl Marx>, (New York: Harper & Row, 1971) p. 155. |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
-- C |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
The thanks for the quote as well as for thinking of the |
821
|
|
|
|
|
|
|
name "Class::Classless" go to Veblen, who can be seen making |
822
|
|
|
|
|
|
|
that secret potato soup of his at |
823
|
|
|
|
|
|
|
C |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
Thanks to my many minions in EFNet #perl for help, suggestions, and |
826
|
|
|
|
|
|
|
encouragement. Especial thanks to Merlyn, Halfjack, and Skrewtape for |
827
|
|
|
|
|
|
|
assuring me that the idea of objects-without-class wasn't just some |
828
|
|
|
|
|
|
|
Felliniesque fever dream I had, but is a concept that has precedent in |
829
|
|
|
|
|
|
|
other programming languages. |
830
|
|
|
|
|
|
|
|
831
|
|
|
|
|
|
|
And thanks to Damian Conway for stritching the brines of his poor |
832
|
|
|
|
|
|
|
students with this module. |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
=head1 SEE ALSO |
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
For information on Perl's classy OOP system, see L, |
837
|
|
|
|
|
|
|
L, L, and |
838
|
|
|
|
|
|
|
Damian Conway's excellent book I |
839
|
|
|
|
|
|
|
Manning Press. |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
=head1 COPYRIGHT |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
Copyright (c) 1999, 2000 Sean M. Burke. All rights reserved. |
844
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
846
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
=head1 AUTHOR |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
Sean M. Burke, sburke@cpan.org |
851
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
=cut |
853
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
########################################################################### |
855
|
|
|
|
|
|
|
########################################################################### |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
$Class::Classless::NAMES = 0; |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
# Instantiate the one prototype object, and pack it with all the handy |
860
|
|
|
|
|
|
|
# methods that we want it to have. |
861
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
$ROOT = bless { |
863
|
|
|
|
|
|
|
'PARENTS' => [], # I am the obj that has no parents |
864
|
|
|
|
|
|
|
'NAME' => 'ROOT', |
865
|
|
|
|
|
|
|
'NO_FAIL' => 0, |
866
|
|
|
|
|
|
|
'VERSION' => 0.00, |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
'METHODS' => { |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
'clone' => sub { |
871
|
|
|
|
|
|
|
my $orig = $_[0]; |
872
|
|
|
|
|
|
|
my $new = bless { %$orig }, ref($orig); # copy |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
delete @{$new}{grep m/^[A-Z]/s, keys %$new}; |
875
|
|
|
|
|
|
|
# Delete entries whose keys start with A-Z |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
# Now define some niceties: |
878
|
|
|
|
|
|
|
$new->{'PARENTS'} = [ $orig ]; |
879
|
|
|
|
|
|
|
$new->{'METHODS'} = { }; |
880
|
|
|
|
|
|
|
$new->{'NAME'} = 'x_' . $Class::Classless::NAMES++; |
881
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
$new->{'ISA_CACHE'} = 1 if $orig->{'ISA_CACHE'}; |
883
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
return $new; |
885
|
|
|
|
|
|
|
}, |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
'polyclone' => sub { # make a new obj be a clone of all of |
888
|
|
|
|
|
|
|
# $X->polyclone($Y, $Z...) |
889
|
|
|
|
|
|
|
my @origs = @_; |
890
|
|
|
|
|
|
|
splice(@origs, 1, 1); # snip out the callstate |
891
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
if($Debug) { |
893
|
|
|
|
|
|
|
print "Parameters to polyclone: ", join(' ',@origs), "\n"; |
894
|
|
|
|
|
|
|
} |
895
|
|
|
|
|
|
|
foreach my $o (@origs) { |
896
|
|
|
|
|
|
|
carp "Parameter $o to polyclone is not an object\n" unless ref($o); |
897
|
|
|
|
|
|
|
} |
898
|
|
|
|
|
|
|
my $new = bless { |
899
|
|
|
|
|
|
|
map(%$_, reverse(@origs)) |
900
|
|
|
|
|
|
|
}, ref($origs[0]); |
901
|
|
|
|
|
|
|
# copy 'em off backwords so the origs[0] overrides all others, etc |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
delete @{$new}{grep m/^[A-Z]/s, keys %$new}; |
904
|
|
|
|
|
|
|
# Delete entries whose keys start with A-Z |
905
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
# Now define some niceties: |
907
|
|
|
|
|
|
|
$new->{'PARENTS'} = \@origs; |
908
|
|
|
|
|
|
|
$new->{'METHODS'} = { }; |
909
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
$new->{'ISA_CACHE'} = 1 if exists $origs[0]{'ISA_CACHE'}; |
911
|
|
|
|
|
|
|
|
912
|
|
|
|
|
|
|
$new->{'NAME'} = 'x_' . $Class::Classless::NAMES++; |
913
|
|
|
|
|
|
|
return $new; |
914
|
|
|
|
|
|
|
}, |
915
|
|
|
|
|
|
|
|
916
|
|
|
|
|
|
|
'FLATTEN' => sub { |
917
|
|
|
|
|
|
|
# Delete all attributes except for ones /^[A-Z]/s |
918
|
|
|
|
|
|
|
delete @{$_[0]}{ grep !m/^[A-Z]/s, keys %{$_[0]} }; |
919
|
|
|
|
|
|
|
return; |
920
|
|
|
|
|
|
|
}, |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
'EXAMINE' => sub { |
923
|
|
|
|
|
|
|
my $in = $_[0]; |
924
|
|
|
|
|
|
|
my($key,$value); |
925
|
|
|
|
|
|
|
print "<$in>\n"; |
926
|
|
|
|
|
|
|
while(($key,$value) = each %$in) { |
927
|
|
|
|
|
|
|
print ' ', Class::Classless::pretty($key, $value), ", \n"; |
928
|
|
|
|
|
|
|
#print " # <$key> <$value>\n"; |
929
|
|
|
|
|
|
|
} |
930
|
|
|
|
|
|
|
return; |
931
|
|
|
|
|
|
|
}, |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
'DESTROY' => \&Class::Classless::X::DESTROY, |
934
|
|
|
|
|
|
|
'ISA_TREE' => \&Class::Classless::X::ISA_TREE, |
935
|
|
|
|
|
|
|
'VERSION' => \&Class::Classless::X::VERSION, |
936
|
|
|
|
|
|
|
'can' => \&Class::Classless::X::can, |
937
|
|
|
|
|
|
|
'isa' => \&Class::Classless::X::isa, |
938
|
|
|
|
|
|
|
# But don't try to override these!! No sirree!! |
939
|
|
|
|
|
|
|
# These are here just so that can() can see them. |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
'get_i' => sub { # get, with interitance |
942
|
|
|
|
|
|
|
croak "usage: \$z = \$it->get_i('attribute_name')" unless @_ == 3; |
943
|
|
|
|
|
|
|
my($it, $attribute) = @_[0,2]; |
944
|
|
|
|
|
|
|
foreach my $ancestor (@{$_[1][2]}) { |
945
|
|
|
|
|
|
|
return $ancestor->{$attribute} if exists $ancestor->{$attribute}; |
946
|
|
|
|
|
|
|
} |
947
|
|
|
|
|
|
|
return undef; # nothing found |
948
|
|
|
|
|
|
|
}, |
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
'put_i' => sub { # put, with inheritance |
951
|
|
|
|
|
|
|
croak "usage: \$it->put_i('attribute_name', \$newval)" unless @_ == 4; |
952
|
|
|
|
|
|
|
my($it, $attribute, $newval) = @_[0,2,3]; |
953
|
|
|
|
|
|
|
foreach my $ancestor (@{$_[1][2]}) { |
954
|
|
|
|
|
|
|
return $ancestor->{$attribute} = $newval |
955
|
|
|
|
|
|
|
if exists $ancestor->{$attribute}; |
956
|
|
|
|
|
|
|
} |
957
|
|
|
|
|
|
|
carp "put_i can't find attribute \"$attribute\" in " |
958
|
|
|
|
|
|
|
. ($it->{'NAME'} || $it) . |
959
|
|
|
|
|
|
|
" or ancestors -- setting it here.\n" if $^W; |
960
|
|
|
|
|
|
|
return $it->{$attribute} = $newval; |
961
|
|
|
|
|
|
|
}, |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
'exists_i' => sub { # exists? with inheritance |
964
|
|
|
|
|
|
|
croak "usage: \$z = \$it->exists_i('attribute_name')" unless @_ == 3; |
965
|
|
|
|
|
|
|
my($it, $attribute) = @_[0,2]; |
966
|
|
|
|
|
|
|
foreach my $ancestor (@{$_[1][2]}) { |
967
|
|
|
|
|
|
|
return 1 if exists $ancestor->{$attribute}; |
968
|
|
|
|
|
|
|
} |
969
|
|
|
|
|
|
|
return 0; # nothing found |
970
|
|
|
|
|
|
|
}, |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
'allcan' => sub { |
973
|
|
|
|
|
|
|
# Return all so-named methods in $it's ISA tree, or () if none. |
974
|
|
|
|
|
|
|
my($it, $m) = @_[0,2]; |
975
|
|
|
|
|
|
|
return unless ref $it; |
976
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
croak "undef is not a valid method name" unless defined($m); |
978
|
|
|
|
|
|
|
croak "null-string is not a valid method name" unless length($m); |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
print "AllCan-seeking method <$m> for <", $it->{'NAME'} || $it, |
981
|
|
|
|
|
|
|
">\n" if $Debug > 1; |
982
|
|
|
|
|
|
|
return |
983
|
|
|
|
|
|
|
map |
984
|
|
|
|
|
|
|
{ |
985
|
|
|
|
|
|
|
( ref($_->{'METHODS'} || 0) # sanity |
986
|
|
|
|
|
|
|
&& exists($_->{'METHODS'}{$m}) |
987
|
|
|
|
|
|
|
) |
988
|
|
|
|
|
|
|
? $_->{'METHODS'}{$m} : () |
989
|
|
|
|
|
|
|
} |
990
|
|
|
|
|
|
|
@{$_[1][2]}; |
991
|
|
|
|
|
|
|
}, |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
'howcan' => sub { |
994
|
|
|
|
|
|
|
# like allcan, but returns a list consisting of pairs, where |
995
|
|
|
|
|
|
|
# each pair is the object that provides the so-named method |
996
|
|
|
|
|
|
|
# and then the value of the method |
997
|
|
|
|
|
|
|
my($it, $m) = @_[0,2]; |
998
|
|
|
|
|
|
|
return unless ref $it; |
999
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
croak "undef is not a valid method name" unless defined($m); |
1001
|
|
|
|
|
|
|
croak "null-string is not a valid method name" unless length($m); |
1002
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
print "AllCan-seeking method <$m> for <", $it->{'NAME'} || $it, |
1004
|
|
|
|
|
|
|
">\n" if $Debug > 1; |
1005
|
|
|
|
|
|
|
return |
1006
|
|
|
|
|
|
|
map |
1007
|
|
|
|
|
|
|
{ |
1008
|
|
|
|
|
|
|
( ref($_->{'METHODS'} || 0) # sanity |
1009
|
|
|
|
|
|
|
&& exists($_->{'METHODS'}{$m}) |
1010
|
|
|
|
|
|
|
) |
1011
|
|
|
|
|
|
|
? ($_, $_->{'METHODS'}{$m}) : () |
1012
|
|
|
|
|
|
|
} |
1013
|
|
|
|
|
|
|
@{$_[1][2]}; |
1014
|
|
|
|
|
|
|
}, |
1015
|
|
|
|
|
|
|
|
1016
|
|
|
|
|
|
|
# deep voodoo... |
1017
|
|
|
|
|
|
|
'memoize_lineage' => sub { |
1018
|
|
|
|
|
|
|
$_[0]{'ISA_CACHE'} ||= $_[1][2]; # copy it right from the callstate |
1019
|
|
|
|
|
|
|
return $_[0]; |
1020
|
|
|
|
|
|
|
}, |
1021
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
'unmemoize_lineage' => sub { |
1023
|
|
|
|
|
|
|
delete $_[0]->{'ISA_CACHE'}; |
1024
|
|
|
|
|
|
|
return $_[0]; |
1025
|
|
|
|
|
|
|
}, |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
'is_lineage_memoized' => sub { |
1028
|
|
|
|
|
|
|
return exists $_[0]{'ISA_CACHE'}; |
1029
|
|
|
|
|
|
|
} |
1030
|
|
|
|
|
|
|
|
1031
|
|
|
|
|
|
|
## |
1032
|
|
|
|
|
|
|
# |
1033
|
|
|
|
|
|
|
# Bad idea -- because if you've changed the real lineage, |
1034
|
|
|
|
|
|
|
# even the call to $thing->reset_memoize_lineage will use |
1035
|
|
|
|
|
|
|
# a corrupted lineage in trying to look up this method. |
1036
|
|
|
|
|
|
|
#'reset_memoize_lineage' => sub { |
1037
|
|
|
|
|
|
|
# $_[0]{'ISA_CACHE'} = 1; |
1038
|
|
|
|
|
|
|
# Class::Classless::X::ISA_TREE($_[0]); # force-set now. |
1039
|
|
|
|
|
|
|
# return $_[0]; |
1040
|
|
|
|
|
|
|
#}, |
1041
|
|
|
|
|
|
|
# |
1042
|
|
|
|
|
|
|
#* $thing->reset_memoize_lineage -- If you are using lineage |
1043
|
|
|
|
|
|
|
#memoization and I change $thing's ancestry, you can reset its |
1044
|
|
|
|
|
|
|
#cache using this method, to force it to take note of any changes in |
1045
|
|
|
|
|
|
|
#its ancestry. If lineage memoization is off, this turns it on. Like |
1046
|
|
|
|
|
|
|
#$thing->memoize_lineage, this returns $thing. |
1047
|
|
|
|
|
|
|
# |
1048
|
|
|
|
|
|
|
## |
1049
|
|
|
|
|
|
|
|
1050
|
|
|
|
|
|
|
}, # end of METHODS hash. |
1051
|
|
|
|
|
|
|
}, |
1052
|
|
|
|
|
|
|
'Class::Classless::X' # the class where classless things live! |
1053
|
|
|
|
|
|
|
; |
1054
|
|
|
|
|
|
|
# End of creating $ROOT and its methods. |
1055
|
|
|
|
|
|
|
|
1056
|
|
|
|
|
|
|
*Class::Classless::X::VERSION = \( $ROOT->{'VERSION'} ); # alias it |
1057
|
|
|
|
|
|
|
@Class::Classless::X::ISA = (); |
1058
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
########################################################################### |
1060
|
|
|
|
|
|
|
########################################################################### |
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
sub Class::Classless::X::AUTOLOAD { |
1063
|
|
|
|
|
|
|
# This's the big dispatcher. |
1064
|
|
|
|
|
|
|
|
1065
|
15
|
|
|
15
|
|
403
|
my $it = shift @_; |
1066
|
15
|
50
|
|
|
|
105
|
my $m = ($Class::Classless::X::AUTOLOAD =~ m/([^:]+)$/s ) |
1067
|
|
|
|
|
|
|
? $1 : $Class::Classless::X::AUTOLOAD; |
1068
|
|
|
|
|
|
|
|
1069
|
15
|
50
|
|
|
|
33
|
croak "Can't call Class::Classless methods (like $m) without an object" |
1070
|
|
|
|
|
|
|
unless ref $it; # sanity, basically. |
1071
|
|
|
|
|
|
|
|
1072
|
15
|
|
|
|
|
14
|
my $prevstate; |
1073
|
15
|
50
|
66
|
|
|
51
|
$prevstate = ${shift @_} |
|
0
|
|
66
|
|
|
0
|
|
1074
|
|
|
|
|
|
|
if scalar(@_) && defined($_[0]) && |
1075
|
|
|
|
|
|
|
ref($_[0]) eq 'Class::Classless::CALLSTATE::SHIMMY' |
1076
|
|
|
|
|
|
|
; # A shim! we were called via $callstate->NEXT |
1077
|
|
|
|
|
|
|
|
1078
|
15
|
0
|
0
|
|
|
29
|
print "\nAbout to call method <$m> on object <", |
|
|
50
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
$it->{'NAME'} || $it, |
1080
|
|
|
|
|
|
|
">", $prevstate ? ' with a shim' : '', |
1081
|
|
|
|
|
|
|
"\n" if $Debug > 1; |
1082
|
|
|
|
|
|
|
|
1083
|
15
|
50
|
|
|
|
23
|
my $no_fail = $prevstate ? $prevstate->[3] : undef; |
1084
|
15
|
50
|
|
|
|
25
|
my $i = $prevstate ? ($prevstate->[1] + 1) : 0; |
1085
|
|
|
|
|
|
|
# where to start scanning |
1086
|
15
|
|
|
|
|
15
|
my $lineage; |
1087
|
|
|
|
|
|
|
|
1088
|
|
|
|
|
|
|
# Get the linearization of the ISA tree |
1089
|
15
|
50
|
33
|
|
|
53
|
if($prevstate) { |
|
|
50
|
|
|
|
|
|
1090
|
0
|
|
|
|
|
0
|
$lineage = $prevstate->[2]; |
1091
|
|
|
|
|
|
|
} elsif(defined $it->{'ISA_CACHE'} and ref $it->{'ISA_CACHE'} ){ |
1092
|
0
|
|
|
|
|
0
|
$lineage = $it->{'ISA_CACHE'}; |
1093
|
|
|
|
|
|
|
} else { |
1094
|
15
|
|
|
|
|
29
|
$lineage = [ &Class::Classless::X::ISA_TREE($it) ]; |
1095
|
|
|
|
|
|
|
} |
1096
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
# Was: |
1098
|
|
|
|
|
|
|
#my @lineage = |
1099
|
|
|
|
|
|
|
# $prevstate ? @{$prevstate->[2]} |
1100
|
|
|
|
|
|
|
# : &Class::Classless::X::ISA_TREE($it); |
1101
|
|
|
|
|
|
|
# # Get the linearization of the ISA tree |
1102
|
|
|
|
|
|
|
# # ISA-memoization happens in the ISA_TREE function. |
1103
|
|
|
|
|
|
|
|
1104
|
15
|
|
|
|
|
39
|
for(; $i < @$lineage; ++$i) { |
1105
|
38
|
50
|
0
|
|
|
72
|
print "Looking in ", $lineage->[$i]{'NAME'} || $lineage->[$i], "\n" |
1106
|
|
|
|
|
|
|
if $Debug; |
1107
|
|
|
|
|
|
|
|
1108
|
38
|
100
|
66
|
|
|
144
|
if( !defined($no_fail) and exists($lineage->[$i]{'NO_FAIL'}) ) { |
1109
|
10
|
|
50
|
|
|
52
|
$no_fail = ($lineage->[$i]{'NO_FAIL'} || 0); |
1110
|
|
|
|
|
|
|
# so the first NO_FAIL sets it |
1111
|
10
|
50
|
0
|
|
|
18
|
print |
1112
|
|
|
|
|
|
|
"Setting no_fail for this call to $no_fail from ", |
1113
|
|
|
|
|
|
|
$lineage->[$i]{'NAME'} || $lineage->[$i], "\n" |
1114
|
|
|
|
|
|
|
if $Debug; |
1115
|
|
|
|
|
|
|
} |
1116
|
|
|
|
|
|
|
|
1117
|
38
|
100
|
50
|
|
|
226
|
if( ref($lineage->[$i]{'METHODS'} || 0) # sanity |
|
|
|
66
|
|
|
|
|
1118
|
|
|
|
|
|
|
&& exists($lineage->[$i]{'METHODS'}{$m}) |
1119
|
|
|
|
|
|
|
){ |
1120
|
|
|
|
|
|
|
# We found what we were after. Now see what to do with it. |
1121
|
15
|
|
|
|
|
22
|
my $v = $lineage->[$i]{'METHODS'}{$m}; |
1122
|
15
|
100
|
100
|
|
|
69
|
return $v unless defined $v and ref $v; |
1123
|
|
|
|
|
|
|
|
1124
|
13
|
100
|
|
|
|
26
|
if(ref($v) eq 'CODE') { # normal case, I expect! |
1125
|
|
|
|
|
|
|
# Used to have copying of the arglist here. |
1126
|
|
|
|
|
|
|
# But it was apparently useless, so I deleted it |
1127
|
11
|
50
|
|
|
|
57
|
unshift @_, |
1128
|
|
|
|
|
|
|
$it, # $_[0] -- target object |
1129
|
|
|
|
|
|
|
# a NEW callstate |
1130
|
|
|
|
|
|
|
bless([$m, $i, $lineage, $no_fail, $prevstate ? 1 : 0], |
1131
|
|
|
|
|
|
|
'Class::Classless::CALLSTATE' |
1132
|
|
|
|
|
|
|
), # $_[1] -- the callstate |
1133
|
|
|
|
|
|
|
; |
1134
|
11
|
|
|
|
|
13
|
goto &{ $v }; # yes, magic goto! bimskalabim! |
|
11
|
|
|
|
|
38
|
|
1135
|
|
|
|
|
|
|
} |
1136
|
2
|
100
|
|
|
|
15
|
return @$v if ref($v) eq '_deref_array'; |
1137
|
1
|
50
|
|
|
|
10
|
return $$v if ref($v) eq '_deref_scalar'; |
1138
|
0
|
|
|
|
|
0
|
return $v; # fallthru |
1139
|
|
|
|
|
|
|
} |
1140
|
|
|
|
|
|
|
} |
1141
|
|
|
|
|
|
|
|
1142
|
0
|
0
|
|
|
|
0
|
if($m eq 'DESTROY') { # mitigate DESTROY-lookup failure at global destruction |
1143
|
0
|
0
|
|
|
|
0
|
print "Ignoring failed DESTROY lookup\n" if $Debug; |
1144
|
|
|
|
|
|
|
# should be impossible |
1145
|
|
|
|
|
|
|
} else { |
1146
|
0
|
0
|
0
|
|
|
0
|
if($no_fail || 0) { |
1147
|
0
|
0
|
0
|
|
|
0
|
print "Ignoring lookup failure on ", |
|
|
0
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
$prevstate ? 'NEXT method' : 'method', |
1149
|
|
|
|
|
|
|
" $m in ", $it->{'NAME'} || $it, |
1150
|
|
|
|
|
|
|
" or any ancestors\n" if $Debug; |
1151
|
0
|
|
|
|
|
0
|
return; |
1152
|
|
|
|
|
|
|
} |
1153
|
0
|
0
|
0
|
|
|
0
|
croak "Can't find ", $prevstate ? 'NEXT method' : 'method', |
1154
|
|
|
|
|
|
|
" $m in ", $it->{'NAME'} || $it, |
1155
|
|
|
|
|
|
|
" or any ancestors\n"; |
1156
|
|
|
|
|
|
|
} |
1157
|
|
|
|
|
|
|
} |
1158
|
|
|
|
|
|
|
|
1159
|
|
|
|
|
|
|
########################################################################### |
1160
|
|
|
|
|
|
|
########################################################################### |
1161
|
|
|
|
|
|
|
|
1162
|
0
|
|
|
0
|
|
0
|
sub Class::Classless::X::DESTROY { |
1163
|
|
|
|
|
|
|
# noop |
1164
|
|
|
|
|
|
|
} |
1165
|
|
|
|
|
|
|
|
1166
|
|
|
|
|
|
|
########################################################################### |
1167
|
|
|
|
|
|
|
sub Class::Classless::X::ISA_TREE { |
1168
|
|
|
|
|
|
|
# The linearizer! |
1169
|
|
|
|
|
|
|
# Returns the search path for $_[0], starting with $_[0] |
1170
|
|
|
|
|
|
|
# Possibly memoized. |
1171
|
|
|
|
|
|
|
|
1172
|
|
|
|
|
|
|
# I stopped being able to understand this algorithm about five |
1173
|
|
|
|
|
|
|
# minutes after I wrote it. |
1174
|
2
|
|
|
2
|
|
17
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
4447
|
|
1175
|
|
|
|
|
|
|
|
1176
|
17
|
|
|
17
|
|
114
|
my $set_cache = 0; # flag to set the cache on the way out |
1177
|
|
|
|
|
|
|
|
1178
|
17
|
50
|
|
|
|
42
|
if(exists($_[0]{'ISA_CACHE'})) { |
1179
|
0
|
0
|
0
|
|
|
0
|
return @{$_[0]{'ISA_CACHE'}} |
|
0
|
|
|
|
|
0
|
|
1180
|
|
|
|
|
|
|
if defined $_[0]{'ISA_CACHE'} |
1181
|
|
|
|
|
|
|
and ref $_[0]{'ISA_CACHE'}; |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
# Otherwise, if exists but is not a ref, it's a signal that it should |
1184
|
|
|
|
|
|
|
# be replaced at the earliest, with a listref |
1185
|
0
|
|
|
|
|
0
|
$set_cache = 1; |
1186
|
|
|
|
|
|
|
} |
1187
|
|
|
|
|
|
|
|
1188
|
17
|
50
|
0
|
|
|
37
|
print "ISA_TREEing for <", $_[0]{'NAME'} || $_[0], ">\n" |
1189
|
|
|
|
|
|
|
if $Debug > 1; |
1190
|
|
|
|
|
|
|
|
1191
|
17
|
|
|
|
|
17
|
my $has_mi = 0; # set to 0 on the first node we see with 2 parents! |
1192
|
|
|
|
|
|
|
# First, just figure out what's in the tree. |
1193
|
17
|
|
|
|
|
58
|
my %last_child = ($_[0] => 1); # as if already seen |
1194
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
# if $last_child{$x} == $y, that means: |
1196
|
|
|
|
|
|
|
# 1) incidentally, we've passed the node $x before. |
1197
|
|
|
|
|
|
|
# 2) $x is the last child of $y, |
1198
|
|
|
|
|
|
|
# so that means that $y can be pushed to the stack only after |
1199
|
|
|
|
|
|
|
# we've pushed $x to the stack. |
1200
|
|
|
|
|
|
|
|
1201
|
17
|
|
|
|
|
19
|
my @tree_nodes; |
1202
|
|
|
|
|
|
|
{ |
1203
|
17
|
|
|
|
|
15
|
my $current; |
|
17
|
|
|
|
|
17
|
|
1204
|
17
|
|
|
|
|
24
|
my @in_stack = ($_[0]); |
1205
|
17
|
|
|
|
|
38
|
while(@in_stack) { |
1206
|
|
|
|
|
|
|
next unless |
1207
|
92
|
50
|
33
|
|
|
696
|
defined($current = shift @in_stack) |
|
|
|
50
|
|
|
|
|
|
|
|
33
|
|
|
|
|
1208
|
|
|
|
|
|
|
&& ref($current) # sanity |
1209
|
|
|
|
|
|
|
&& ref($current->{'PARENTS'} || 0) # sanity |
1210
|
|
|
|
|
|
|
; |
1211
|
|
|
|
|
|
|
|
1212
|
92
|
|
|
|
|
99
|
push @tree_nodes, $current; |
1213
|
|
|
|
|
|
|
|
1214
|
92
|
100
|
|
|
|
87
|
$has_mi = 1 if @{$current->{'PARENTS'}} > 1; |
|
92
|
|
|
|
|
211
|
|
1215
|
|
|
|
|
|
|
unshift |
1216
|
|
|
|
|
|
|
@in_stack, |
1217
|
|
|
|
|
|
|
map { |
1218
|
95
|
100
|
|
|
|
211
|
if(exists $last_child{$_}) { # seen before! |
|
92
|
|
|
|
|
144
|
|
1219
|
20
|
|
|
|
|
33
|
$last_child{$_} = $current; |
1220
|
20
|
|
|
|
|
48
|
(); # seen -- don't re-explore |
1221
|
|
|
|
|
|
|
} else { # first time seen |
1222
|
75
|
|
|
|
|
130
|
$last_child{$_} = $current; |
1223
|
75
|
|
|
|
|
304
|
$_; # first time seen -- explore now |
1224
|
|
|
|
|
|
|
} |
1225
|
|
|
|
|
|
|
} |
1226
|
92
|
|
|
|
|
92
|
@{$current->{'PARENTS'}} |
1227
|
|
|
|
|
|
|
; |
1228
|
|
|
|
|
|
|
} |
1229
|
|
|
|
|
|
|
|
1230
|
17
|
0
|
|
|
|
31
|
print "Contents of tree_nodes: ", nodelist(@tree_nodes), |
|
|
50
|
|
|
|
|
|
1231
|
|
|
|
|
|
|
$has_mi ? " (has MI)\n" : " (no MI)\n" |
1232
|
|
|
|
|
|
|
if $Debug > 1; |
1233
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
# If there was no MI, then that first scan was sufficient. |
1235
|
17
|
100
|
|
|
|
34
|
unless($has_mi) { |
1236
|
9
|
50
|
|
|
|
13
|
$_[0]{'ISA_CACHE'} = \@tree_nodes if $set_cache; |
1237
|
9
|
|
|
|
|
35
|
return @tree_nodes; |
1238
|
|
|
|
|
|
|
} |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
# Otherwise, toss this list and rescan, consulting %last_child |
1241
|
|
|
|
|
|
|
} |
1242
|
|
|
|
|
|
|
|
1243
|
|
|
|
|
|
|
# $last_child{$parent} holds the last (or only) child of $parent |
1244
|
|
|
|
|
|
|
# in this tree. When walking the tree this time, only that |
1245
|
|
|
|
|
|
|
# child is authorized to put its parent on the @in_stack. |
1246
|
|
|
|
|
|
|
# And that's the only way a node can get added to @in_stack, |
1247
|
|
|
|
|
|
|
# except for $_[0] (the start node) being there at the beginning. |
1248
|
|
|
|
|
|
|
|
1249
|
|
|
|
|
|
|
# Now, walk again, but this time exploring parents the LAST |
1250
|
|
|
|
|
|
|
# time seen in the tree, not the first. |
1251
|
|
|
|
|
|
|
|
1252
|
8
|
|
|
|
|
9
|
my @out; |
1253
|
|
|
|
|
|
|
{ |
1254
|
8
|
|
|
|
|
9
|
my $current; |
|
8
|
|
|
|
|
8
|
|
1255
|
8
|
|
|
|
|
12
|
my @in_stack = ($_[0]); |
1256
|
8
|
|
|
|
|
17
|
while(@in_stack) { |
1257
|
75
|
50
|
33
|
|
|
307
|
next unless defined($current = shift @in_stack) && ref($current); |
1258
|
75
|
|
|
|
|
87
|
push @out, $current; # finally. |
1259
|
75
|
|
|
|
|
741
|
unshift |
1260
|
|
|
|
|
|
|
@in_stack, |
1261
|
|
|
|
|
|
|
grep( |
1262
|
|
|
|
|
|
|
( |
1263
|
|
|
|
|
|
|
defined($_) # sanity |
1264
|
|
|
|
|
|
|
&& ref($_) # sanity |
1265
|
|
|
|
|
|
|
&& $last_child{$_} eq $current, |
1266
|
|
|
|
|
|
|
), |
1267
|
|
|
|
|
|
|
# I'm lastborn (or onlyborn) of this parent |
1268
|
|
|
|
|
|
|
# so it's OK to explore now |
1269
|
75
|
50
|
66
|
|
|
254
|
@{$current->{'PARENTS'}} |
|
|
|
50
|
|
|
|
|
1270
|
|
|
|
|
|
|
) |
1271
|
|
|
|
|
|
|
if ref($current->{'PARENTS'} || 0) # sanity |
1272
|
|
|
|
|
|
|
; |
1273
|
|
|
|
|
|
|
} |
1274
|
|
|
|
|
|
|
|
1275
|
8
|
50
|
|
|
|
23
|
unless(scalar(@out) == scalar(keys(%last_child))) { |
1276
|
|
|
|
|
|
|
# the counts should be equal |
1277
|
0
|
|
|
|
|
0
|
my %good_ones; |
1278
|
0
|
|
|
|
|
0
|
@good_ones{@out} = (); |
1279
|
0
|
0
|
|
|
|
0
|
croak |
1280
|
|
|
|
|
|
|
"ISA tree for " . |
1281
|
|
|
|
|
|
|
($_[0]{'NAME'} || $_[0]) . |
1282
|
|
|
|
|
|
|
" is apparently cyclic, probably involving the nodes " . |
1283
|
0
|
|
0
|
|
|
0
|
nodelist( grep { ref($_) && !exists $good_ones{$_} } |
1284
|
|
|
|
|
|
|
values(%last_child) ) |
1285
|
|
|
|
|
|
|
. "\n"; |
1286
|
|
|
|
|
|
|
} |
1287
|
|
|
|
|
|
|
} |
1288
|
|
|
|
|
|
|
#print "Contents of out: ", nodelist(@out), "\n"; |
1289
|
|
|
|
|
|
|
|
1290
|
8
|
50
|
|
|
|
16
|
$_[0]{'ISA_CACHE'} = \@out if $set_cache; |
1291
|
8
|
|
|
|
|
55
|
return @out; |
1292
|
|
|
|
|
|
|
} |
1293
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
########################################################################### |
1295
|
|
|
|
|
|
|
|
1296
|
|
|
|
|
|
|
sub Class::Classless::X::can { # NOT like UNIVERSAL::can ... |
1297
|
|
|
|
|
|
|
# return 1 if $it is capable of the method given -- otherwise 0 |
1298
|
0
|
|
|
0
|
|
|
my($it, $m) = @_[0,1]; |
1299
|
0
|
0
|
|
|
|
|
return undef unless ref $it; |
1300
|
|
|
|
|
|
|
|
1301
|
0
|
0
|
|
|
|
|
croak "undef is not a valid method name" unless defined($m); |
1302
|
0
|
0
|
|
|
|
|
croak "null-string is not a valid method name" unless length($m); |
1303
|
|
|
|
|
|
|
|
1304
|
0
|
0
|
0
|
|
|
|
print "Can-seeking method <$m> for <", $it->{'NAME'} || $it, |
1305
|
|
|
|
|
|
|
">\n" if $Debug > 1; |
1306
|
|
|
|
|
|
|
|
1307
|
0
|
|
|
|
|
|
foreach my $o (&Class::Classless::X::ISA_TREE($it)) { |
1308
|
0
|
0
|
0
|
|
|
|
return 1 |
|
|
|
0
|
|
|
|
|
1309
|
|
|
|
|
|
|
if ref($o->{'METHODS'} || 0) # sanity |
1310
|
|
|
|
|
|
|
&& exists $o->{'METHODS'}{$m}; |
1311
|
|
|
|
|
|
|
} |
1312
|
|
|
|
|
|
|
|
1313
|
0
|
|
|
|
|
|
return 0; |
1314
|
|
|
|
|
|
|
} |
1315
|
|
|
|
|
|
|
|
1316
|
|
|
|
|
|
|
########################################################################### |
1317
|
|
|
|
|
|
|
|
1318
|
|
|
|
|
|
|
sub Class::Classless::X::VERSION { |
1319
|
|
|
|
|
|
|
# like UNIVERSAL::VERSION. |
1320
|
0
|
0
|
0
|
0
|
|
|
print "Searching in ", ( $_[0]->{'NAME'} || $_[0] ), |
1321
|
|
|
|
|
|
|
" for VERSION\n" if $Debug; |
1322
|
0
|
0
|
|
|
|
|
if(defined($_[1])) { |
1323
|
0
|
|
|
|
|
|
my $v = $_[0]->get_i('VERSION'); |
1324
|
0
|
0
|
|
|
|
|
$v = '' unless defined $v; # insanity |
1325
|
0
|
0
|
0
|
|
|
|
croak(( $_[0]->{'NAME'} || $_[0]) |
1326
|
|
|
|
|
|
|
. " version $_[1] required--this is only version $v" |
1327
|
|
|
|
|
|
|
) |
1328
|
|
|
|
|
|
|
if $v < $_[1]; |
1329
|
0
|
|
|
|
|
|
return $v; |
1330
|
|
|
|
|
|
|
} else { |
1331
|
|
|
|
|
|
|
#print "V<", $_[0]->get_i('VERSION'), ">\n"; |
1332
|
0
|
|
|
|
|
|
return $_[0]->get_i('VERSION'); |
1333
|
|
|
|
|
|
|
} |
1334
|
|
|
|
|
|
|
} |
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
########################################################################### |
1337
|
|
|
|
|
|
|
|
1338
|
|
|
|
|
|
|
sub Class::Classless::X::isa { # Like UNIVERSAL::isa |
1339
|
|
|
|
|
|
|
# Returns true for $X->isa($Y) iff $Y is $X or is an ancestor of $X. |
1340
|
|
|
|
|
|
|
|
1341
|
0
|
0
|
0
|
0
|
|
|
return unless ref($_[0]) && ref($_[1]); |
1342
|
0
|
0
|
0
|
|
|
|
print "Testing isa for ", ( $_[0]->{'NAME'} || $_[0] ), |
|
|
|
0
|
|
|
|
|
1343
|
|
|
|
|
|
|
" and ", ( $_[1]->{'NAME'} || $_[1] ), "\n" if $Debug; |
1344
|
0
|
|
|
|
|
|
return scalar(grep {$_ eq $_[1]} &Class::Classless::X::ISA_TREE($_[0])); |
|
0
|
|
|
|
|
|
|
1345
|
|
|
|
|
|
|
} |
1346
|
|
|
|
|
|
|
|
1347
|
|
|
|
|
|
|
########################################################################### |
1348
|
|
|
|
|
|
|
########################################################################### |
1349
|
|
|
|
|
|
|
########################################################################### |
1350
|
|
|
|
|
|
|
|
1351
|
|
|
|
|
|
|
%Pretty_form = ( |
1352
|
|
|
|
|
|
|
"\a" => '\a', # ding! |
1353
|
|
|
|
|
|
|
"\b" => '\b', # BS |
1354
|
|
|
|
|
|
|
"\e" => '\e', # ESC |
1355
|
|
|
|
|
|
|
"\f" => '\f', # FF |
1356
|
|
|
|
|
|
|
"\t" => '\t', # tab |
1357
|
|
|
|
|
|
|
"\cm" => '\cm', |
1358
|
|
|
|
|
|
|
"\cj" => '\cj', |
1359
|
|
|
|
|
|
|
"\n" => '\n', # probably overrides one of either \cm or \cj |
1360
|
|
|
|
|
|
|
'"' => '\"', |
1361
|
|
|
|
|
|
|
'\\' => '\\\\', |
1362
|
|
|
|
|
|
|
'$' => '\\$', |
1363
|
|
|
|
|
|
|
'@' => '\\@', |
1364
|
|
|
|
|
|
|
'%' => '\\%', |
1365
|
|
|
|
|
|
|
'#' => '\\#', |
1366
|
|
|
|
|
|
|
); |
1367
|
|
|
|
|
|
|
|
1368
|
|
|
|
|
|
|
sub pretty { # for Pretty-Print, but doesn't print |
1369
|
|
|
|
|
|
|
# Based somewhat on MIDI.pm's _dump_quote |
1370
|
0
|
|
|
0
|
0
|
|
my @stuff = @_; # copy |
1371
|
0
|
0
|
0
|
|
|
|
my $Seen = (@stuff |
1372
|
|
|
|
|
|
|
and defined($stuff[0]) |
1373
|
|
|
|
|
|
|
and ref($stuff[0]) eq 'Class::Classless::PRETTYENV' |
1374
|
|
|
|
|
|
|
) |
1375
|
|
|
|
|
|
|
? shift(@stuff) |
1376
|
|
|
|
|
|
|
: bless({}, 'Class::Classless::PRETTYENV'); |
1377
|
|
|
|
|
|
|
# $Seen is my hash for noting what structures I've already explored. |
1378
|
|
|
|
|
|
|
|
1379
|
0
|
0
|
0
|
|
|
|
my $out = |
|
|
|
0
|
|
|
|
|
1380
|
|
|
|
|
|
|
join(",\n", |
1381
|
|
|
|
|
|
|
map |
1382
|
|
|
|
|
|
|
{ # the cleaner-upper function |
1383
|
0
|
|
|
|
|
|
$_ = $_->{'NAME'} |
1384
|
|
|
|
|
|
|
if defined($_) |
1385
|
|
|
|
|
|
|
&& ref($_) eq 'Class::Classless::X' |
1386
|
|
|
|
|
|
|
&& $_->{'NAME'} |
1387
|
|
|
|
|
|
|
; |
1388
|
|
|
|
|
|
|
|
1389
|
0
|
0
|
0
|
|
|
|
if(!defined($_)) { # undef |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1390
|
0
|
|
|
|
|
|
"undef"; |
1391
|
|
|
|
|
|
|
|
1392
|
|
|
|
|
|
|
} elsif(ref($_) eq 'ARRAY') { # arrayref |
1393
|
0
|
0
|
|
|
|
|
$Seen->{$_}++ |
1394
|
|
|
|
|
|
|
? "\'$_\'" |
1395
|
|
|
|
|
|
|
: ("[ " . &pretty($Seen, @$_) . " ]") |
1396
|
|
|
|
|
|
|
; |
1397
|
|
|
|
|
|
|
} elsif(ref($_) eq 'HASH') { # hashref |
1398
|
0
|
0
|
|
|
|
|
$Seen->{$_}++ |
1399
|
|
|
|
|
|
|
? "\'$_\'" |
1400
|
|
|
|
|
|
|
: ("{ " . &pretty($Seen, %$_) . " }") |
1401
|
|
|
|
|
|
|
; |
1402
|
|
|
|
|
|
|
|
1403
|
|
|
|
|
|
|
} elsif(!length($_)) { # empty string |
1404
|
0
|
|
|
|
|
|
"''"; |
1405
|
|
|
|
|
|
|
|
1406
|
|
|
|
|
|
|
} elsif($_ eq '0' or m/^-?(?:[1-9]\d*)$/s) { # integers |
1407
|
|
|
|
|
|
|
# Was just: m/^-?\d+(?:\.\d+)?$/s |
1408
|
|
|
|
|
|
|
# but that's over-broad, as let "0123" thru, which is |
1409
|
|
|
|
|
|
|
# wrong, since that's octal 0123, == decimal 83. |
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
# m/^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)?$/s and $_ ne '-0' |
1412
|
|
|
|
|
|
|
# would let thru all well-formed numbers, but also |
1413
|
|
|
|
|
|
|
# non-canonical forms of them like 0.3000000. |
1414
|
|
|
|
|
|
|
# Better to just stick to integers I think. |
1415
|
0
|
|
|
|
|
|
$_; |
1416
|
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
} elsif( # text with junk in it |
1418
|
|
|
|
|
|
|
#s<([^\x20\x21\x23\x27-\x3F\x41-\x5B\x5D-\x7E])> |
1419
|
|
|
|
|
|
|
# <'\\x'.(unpack("H2",$1))>eg |
1420
|
|
|
|
|
|
|
s<([^\x20\x21\x23\x27-\x3F\x41-\x5B\x5D-\x7E])> |
1421
|
0
|
0
|
|
|
|
|
<$Pretty_form{$1} || '\\x'.(unpack("H2",$1))>eg |
1422
|
|
|
|
|
|
|
) { |
1423
|
0
|
|
|
|
|
|
"\"$_\""; |
1424
|
|
|
|
|
|
|
} else { # text with no junk in it |
1425
|
0
|
|
|
|
|
|
s<'><\\'>g; |
1426
|
0
|
|
|
|
|
|
"\'$_\'"; |
1427
|
|
|
|
|
|
|
} |
1428
|
|
|
|
|
|
|
} |
1429
|
|
|
|
|
|
|
@stuff |
1430
|
|
|
|
|
|
|
) |
1431
|
|
|
|
|
|
|
; |
1432
|
0
|
|
|
|
|
|
$out =~ tr<\n>< > if 1; #length($out) < 72; |
1433
|
0
|
|
|
|
|
|
return $out; |
1434
|
|
|
|
|
|
|
} |
1435
|
|
|
|
|
|
|
|
1436
|
|
|
|
|
|
|
########################################################################### |
1437
|
|
|
|
|
|
|
|
1438
|
0
|
|
0
|
0
|
0
|
|
sub nodelist { join ', ', map { "" . ($_->{'NAME'} || $_) . ""} @_ } |
|
0
|
|
|
|
|
|
|
1439
|
|
|
|
|
|
|
|
1440
|
|
|
|
|
|
|
########################################################################### |
1441
|
|
|
|
|
|
|
########################################################################### |
1442
|
|
|
|
|
|
|
########################################################################### |
1443
|
|
|
|
|
|
|
# Methods for the CALLSTATE class. |
1444
|
|
|
|
|
|
|
# Basically, CALLSTATE objects represent the state of the dispatcher, |
1445
|
|
|
|
|
|
|
# frozen at the moment when the method call was dispatched to the |
1446
|
|
|
|
|
|
|
# appropriate sub. |
1447
|
|
|
|
|
|
|
# In the grand scheme of things, this needn't be a class -- I could |
1448
|
|
|
|
|
|
|
# have just made the callstate data-object be a hash with documented |
1449
|
|
|
|
|
|
|
# keys, or a closure that responded to only certain parameters, |
1450
|
|
|
|
|
|
|
# etc. But I like it this way. And I like being able to say simply |
1451
|
|
|
|
|
|
|
# $cs->NEXT |
1452
|
|
|
|
|
|
|
# Yes, these are a bit cryptically written, but it's behoovy for |
1453
|
|
|
|
|
|
|
# them to be very very efficient. |
1454
|
|
|
|
|
|
|
|
1455
|
|
|
|
|
|
|
*Class::Classless::CALLSTATE::VERSION = \$Class::Classless::VERSION; |
1456
|
|
|
|
|
|
|
@Class::Classless::ISA = (); |
1457
|
0
|
|
|
0
|
|
|
sub Class::Classless::CALLSTATE::found_name { $_[0][0] } |
1458
|
|
|
|
|
|
|
# the method name called and found |
1459
|
0
|
|
|
0
|
|
|
sub Class::Classless::CALLSTATE::found_depth { $_[0][1] } |
1460
|
|
|
|
|
|
|
# my depth in the lineage |
1461
|
0
|
|
|
0
|
|
|
sub Class::Classless::CALLSTATE::lineage { @{$_[0][2]} } |
|
0
|
|
|
|
|
|
|
1462
|
|
|
|
|
|
|
# my lineage |
1463
|
0
|
|
|
0
|
|
|
sub Class::Classless::CALLSTATE::target { $_[0][2][ 0 ] } |
1464
|
|
|
|
|
|
|
# the object that's the target -- same as $_[0] for the method called |
1465
|
0
|
|
|
0
|
|
|
sub Class::Classless::CALLSTATE::home { $_[0][2][ $_[0][1] ] } |
1466
|
|
|
|
|
|
|
# the object I was found in |
1467
|
|
|
|
|
|
|
sub Class::Classless::CALLSTATE::sub_found { |
1468
|
0
|
|
|
0
|
|
|
$_[0][2][ $_[0][1] ]{'METHODS'}{ $_[0][0] } |
1469
|
|
|
|
|
|
|
} # the routine called |
1470
|
|
|
|
|
|
|
|
1471
|
0
|
|
|
0
|
|
|
sub Class::Classless::CALLSTATE::no_fail { $_[0][3] } |
1472
|
0
|
|
|
0
|
|
|
sub Class::Classless::CALLSTATE::set_no_fail_true { $_[0][3] = 1 } |
1473
|
0
|
|
|
0
|
|
|
sub Class::Classless::CALLSTATE::set_fail_false { $_[0][3] = 0 } |
1474
|
0
|
|
|
0
|
|
|
sub Class::Classless::CALLSTATE::set_fail_undef { $_[0][3] = undef } |
1475
|
|
|
|
|
|
|
|
1476
|
0
|
|
|
0
|
|
|
sub Class::Classless::CALLSTATE::via_next { $_[0][4] } |
1477
|
|
|
|
|
|
|
|
1478
|
|
|
|
|
|
|
sub Class::Classless::CALLSTATE::NEXT { |
1479
|
|
|
|
|
|
|
#croak "NEXT needs at least one argument: \$cs->NEXT('method'...)" |
1480
|
|
|
|
|
|
|
# unless @_ > 1; |
1481
|
|
|
|
|
|
|
# no longer true. |
1482
|
0
|
|
|
0
|
|
|
my $cs = shift @_; |
1483
|
0
|
|
|
|
|
|
my $m = shift @_; # which may be (or come out) undef... |
1484
|
0
|
0
|
|
|
|
|
$m = $cs->[0] unless defined $m; # the method name called and found |
1485
|
|
|
|
|
|
|
|
1486
|
0
|
|
|
|
|
|
($cs->[2][0])->$m( |
1487
|
|
|
|
|
|
|
bless( \$cs, 'Class::Classless::CALLSTATE::SHIMMY' ), |
1488
|
|
|
|
|
|
|
@_ |
1489
|
|
|
|
|
|
|
); |
1490
|
|
|
|
|
|
|
} |
1491
|
|
|
|
|
|
|
|
1492
|
|
|
|
|
|
|
########################################################################### |
1493
|
|
|
|
|
|
|
|
1494
|
|
|
|
|
|
|
1; |
1495
|
|
|
|
|
|
|
|
1496
|
|
|
|
|
|
|
__END__ |