| 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__ |