line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Devel::TypeCheck::Type; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
46
|
|
4
|
1
|
|
|
1
|
|
6
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
121
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
require Exporter; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
9
|
|
|
|
|
|
|
our @EXPORT = (); |
10
|
|
|
|
|
|
|
our @EXPORT_OK = qw(n2s s2n); |
11
|
|
|
|
|
|
|
|
12
|
1
|
|
|
1
|
|
629
|
use Devel::TypeCheck::Util; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
232
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=head1 NAME |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
Devel::TypeCheck::Type - base type for the type language representation of Devel::TypeCheck |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head1 SYNOPSIS |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
Devel::TypeCheck::Type is an abstract class and should not be |
21
|
|
|
|
|
|
|
instantiated directly. However, all types used in the type system are |
22
|
|
|
|
|
|
|
inheritors of this class and rely on methods defined here. |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 DESCRIPTION |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
The data structure is essentially a linked list from Mu at the head of |
27
|
|
|
|
|
|
|
the list to terminal or variable types at the end. Thus, most of the |
28
|
|
|
|
|
|
|
functions defined here support that by relaying the request to the |
29
|
|
|
|
|
|
|
subtype member (the next link in the linked list) instead of actually |
30
|
|
|
|
|
|
|
doing anything themselves. |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
=over 4 |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=cut |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# This is the base class for the object system used to store the types |
37
|
|
|
|
|
|
|
# when computing the run-time type inference. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# **** CLASS **** |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
our $AUTOLOAD; # Package global used in &AUTOLOAD |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
our %name2number; # Mapping type names to numbers from @EXPORTS for &AUTOLOAD |
44
|
|
|
|
|
|
|
our @number2name; # Mapping numbers to names for printing purposes |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
our @SUBTYPES; |
47
|
|
|
|
|
|
|
our @subtypes; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=item B |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Class methods implemented through C<< AUTOLOAD >> to return a unique |
52
|
|
|
|
|
|
|
number for each different function. This is used to represent type |
53
|
|
|
|
|
|
|
for certain queries. |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=cut |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
# Set up the tables for AUTOLOAD, n2s, and s2n operation. |
58
|
|
|
|
|
|
|
BEGIN { |
59
|
1
|
|
|
1
|
|
2
|
my $count = 0; |
60
|
1
|
|
|
|
|
4
|
@EXPORT = qw(VAR M H K P N O X Y Z IO PV IV DV); |
61
|
|
|
|
|
|
|
|
62
|
1
|
|
|
|
|
9
|
for my $i (@EXPORT) { |
63
|
14
|
|
|
|
|
25
|
$number2name[$count] = $i; |
64
|
14
|
|
|
|
|
8080
|
$name2number{$i} = $count++; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# For the Devel::TypeCheck::Type::{VAR,M,H,etc...}() methods |
69
|
|
|
|
|
|
|
sub AUTOLOAD { |
70
|
19
|
|
|
19
|
|
41
|
my $name = $AUTOLOAD; |
71
|
19
|
|
|
|
|
95
|
$name =~ s/.*://; # strip fully-qualified portion |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
# Die if the name this was called by isn't exported |
74
|
19
|
50
|
|
|
|
73
|
if (!exists($name2number{$name})) { |
75
|
0
|
|
|
|
|
0
|
confess("Method &$name not implemented"); |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
19
|
|
|
|
|
100
|
return $name2number{$name}; |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# Number to string lookup on Type subclasses |
82
|
|
|
|
|
|
|
sub n2s ($) { |
83
|
0
|
|
|
0
|
0
|
|
my ($n) = @_; |
84
|
0
|
|
|
|
|
|
return $number2name[$n]; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
# String to number lookup on Type subclasses |
88
|
|
|
|
|
|
|
sub s2n ($) { |
89
|
0
|
|
|
0
|
0
|
|
my ($s) = @_; |
90
|
0
|
|
|
|
|
|
return $name2number{$s}; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
# Required, since AUTOLOAD will suck this up if not defined |
94
|
0
|
|
|
0
|
|
|
sub DESTROY {} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
# **** INSTANCE **** |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=item B($subtype) |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
Create a new Type instance with the given item as the next link in the |
101
|
|
|
|
|
|
|
list data structure. This will control the subtypes allowed, so that |
102
|
|
|
|
|
|
|
illegal types cannot be created when using this constructor. This |
103
|
|
|
|
|
|
|
method is abstract for this class, but works with subtypes. Types are |
104
|
|
|
|
|
|
|
never constructed by the user -- they should always be generated with |
105
|
|
|
|
|
|
|
the fresh* and gen* methods of the type environment, |
106
|
|
|
|
|
|
|
Devel::TypeCheck::Environment. |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=cut |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# Constructor |
111
|
|
|
|
|
|
|
sub new { |
112
|
0
|
|
|
0
|
1
|
|
my ($name, $subtype) = @_; |
113
|
|
|
|
|
|
|
|
114
|
0
|
0
|
|
|
|
|
if ($name eq "Devel::TypeCheck::Type") { |
115
|
0
|
|
|
|
|
|
abstract("new", $name); |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
0
|
0
|
|
|
|
|
if (! $subtype->isa("Devel::TypeCheck::Type")) { |
119
|
0
|
|
|
|
|
|
croak("Subtype is not a member of class Devel::TypeCheck::Type"); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
0
|
|
|
|
|
|
my $this = {}; |
123
|
|
|
|
|
|
|
|
124
|
0
|
|
|
|
|
|
bless($this, $name); |
125
|
|
|
|
|
|
|
|
126
|
0
|
0
|
|
|
|
|
if (! $this->hasSubtype($subtype->type)) { |
127
|
0
|
|
|
|
|
|
croak("Invalid subtype ", n2s($subtype->type), " for class $name"); |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
0
|
|
|
|
|
|
$this->{'subtype'} = $subtype; |
131
|
|
|
|
|
|
|
|
132
|
0
|
|
|
|
|
|
return $this; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=item B |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
Return the numerical type of the instance. |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=cut |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
# Returns the type of an instance |
142
|
|
|
|
|
|
|
sub type { |
143
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
144
|
0
|
|
|
|
|
|
abstract("type", ref($this)); |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=item B |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
Returns the next link in the list. |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=cut |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
# Returns the subtype |
154
|
|
|
|
|
|
|
sub subtype { |
155
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
156
|
0
|
|
|
|
|
|
return $this->{'subtype'}; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=item B($type) |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
Returns true if the given instance has the given type. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=cut |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
# Determines if a given class has a given type as an allowed subtype |
166
|
|
|
|
|
|
|
sub hasSubtype { |
167
|
0
|
|
|
0
|
1
|
|
abstract("hasSubtype", "Devel::TypeCheck::Type"); |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
# Shouldn't ever be called except by a T::Environment or an inheritor of T. |
171
|
|
|
|
|
|
|
sub unify { |
172
|
0
|
|
|
0
|
0
|
|
my ($this, $that, $env) = @_; |
173
|
|
|
|
|
|
|
|
174
|
0
|
|
|
|
|
|
$this = $env->find($this); |
175
|
0
|
|
|
|
|
|
$that = $env->find($that); |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# Make sure that types match and that subtypes are valid. |
178
|
0
|
0
|
0
|
|
|
|
if ($this->type == $that->type && |
|
|
|
0
|
|
|
|
|
179
|
|
|
|
|
|
|
$this->hasSubtype($this->subtype->type) && |
180
|
|
|
|
|
|
|
$that->hasSubtype($that->subtype->type)) { |
181
|
0
|
|
|
|
|
|
return $this->subtype->unify($that->subtype, $env); |
182
|
|
|
|
|
|
|
} else { |
183
|
0
|
|
|
|
|
|
return undef; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# Do the occurs check against $that with the given environment $env. |
188
|
|
|
|
|
|
|
sub occurs { |
189
|
0
|
|
|
0
|
0
|
|
my ($this, $that, $env) = @_; |
190
|
|
|
|
|
|
|
|
191
|
0
|
0
|
|
|
|
|
if ($that->type != Devel::TypeCheck::Type::VAR()) { |
192
|
0
|
|
|
|
|
|
die("Invalid type ", $that->str, " for occurs check"); |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
0
|
|
|
|
|
|
return $this->subtype->occurs($that, $env); |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=item B($env) |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
Return a string constructed from this type and subtypes. This is the |
201
|
|
|
|
|
|
|
"ugly" string as output by the B::TypeCheck backend module. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=cut |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
# Return a readable string |
206
|
|
|
|
|
|
|
sub str { |
207
|
0
|
|
|
0
|
1
|
|
my ($this, $env) = @_; |
208
|
0
|
|
|
|
|
|
return (n2s($this->type) . $this->subtype->str($env)); |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=item B |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
The human readable description of this type. |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
=cut |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub pretty { |
218
|
0
|
|
|
0
|
1
|
|
my ($this, $env) = @_; |
219
|
0
|
|
|
|
|
|
return $this->subtype->pretty($env); |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
=item B($type) |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
Indicate whether some instance in the list of types is the same as the |
225
|
|
|
|
|
|
|
numerical type passed to this method. |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=cut |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
sub is { |
230
|
0
|
|
|
0
|
1
|
|
my ($this, $type) = @_; |
231
|
0
|
0
|
|
|
|
|
if ($this->type == $type) { |
232
|
0
|
|
|
|
|
|
return TRUE; |
233
|
|
|
|
|
|
|
} else { |
234
|
0
|
0
|
|
|
|
|
if (defined($this->subtype)) { |
235
|
0
|
|
|
|
|
|
return $this->subtype->is($type); |
236
|
|
|
|
|
|
|
} else { |
237
|
0
|
|
|
|
|
|
return FALSE(); |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
=item B |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
Return the parent type of the instance. This always returns undef for |
245
|
|
|
|
|
|
|
internal and most terminal types, but returns the variable's parent in |
246
|
|
|
|
|
|
|
the union-find data structure (if it has one). |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=cut |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
# If the return is undefined, then the type has no parent in the type |
251
|
|
|
|
|
|
|
# classes. Incomplete and terminal types act this way. Type |
252
|
|
|
|
|
|
|
# variables return the current type class that they belong to, if any. |
253
|
|
|
|
|
|
|
sub getParent { |
254
|
0
|
|
|
0
|
1
|
|
return undef; |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
=item B |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
True if the type is completely specified and has no unbound type variables. |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
=cut |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
# Returns a boolean value. If TRUE, then the type is complete and has |
264
|
|
|
|
|
|
|
# no type variables. |
265
|
|
|
|
|
|
|
sub complete { |
266
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
267
|
0
|
|
|
|
|
|
return $this->subtype->complete; |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=item B |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
Dereference this type. |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=cut |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
sub deref { |
277
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
278
|
0
|
|
|
|
|
|
return $this->subtype->deref; |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
=item B |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
Whether the underlying array or hash is homogeneous. |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=cut |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub homogeneous { |
288
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
289
|
0
|
|
|
|
|
|
return $this->subtype->homogeneous(); |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=item B |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
The size of the tuple, if the type at the end of the linked list is a |
295
|
|
|
|
|
|
|
tuple type for an array. This fails otherwise. |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=cut |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
sub arity { |
300
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
301
|
0
|
|
|
|
|
|
return $this->subtype->arity; |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=item B |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
Append a given type to an array type. Promotes to homogeneous list as necessary. |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=cut |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
sub append { |
311
|
0
|
|
|
0
|
1
|
|
my ($this, $that, $env) = @_; |
312
|
0
|
|
|
|
|
|
return $this->subtype->append($that, $env, $this); |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=item B |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
Get the underlying tuple from a tuple type. |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=cut |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
sub ary { |
322
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
323
|
0
|
|
|
|
|
|
return $this->subtype->ary(); |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
=item B($index, $env) |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
Dereference the type from the array or hash at the given index. |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=cut |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
sub derefIndex { |
333
|
0
|
|
|
0
|
1
|
|
my ($this, $index, $env) = @_; |
334
|
0
|
|
|
|
|
|
return $this->subtype->derefIndex($index, $env); |
335
|
|
|
|
|
|
|
} |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=item B |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
Dereference the homogeneous type for lists and associative arrays. |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=cut |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
sub derefHomogeneous { |
344
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
345
|
0
|
|
|
|
|
|
return $this->subtype->derefHomogeneous(); |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=item B |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
Generate a list of references from the underlying array. Exists solely to support the srefgen operator on items of array type. |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=cut |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
sub referize { |
355
|
0
|
|
|
0
|
1
|
|
my ($this, $env) = @_; |
356
|
0
|
|
|
|
|
|
return $this->subtype->referize($env); |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=item B |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
Get the scalar type out of a glob type. This is roughly equivalent to C<<*foo{SCALAR}>>. |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=cut |
364
|
|
|
|
|
|
|
sub derefKappa { |
365
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
366
|
0
|
|
|
|
|
|
return $this->subtype->derefKappa(); |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=item B |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
Get the array type out of a glob type. This is roughly equivalent to C<<*foo{ARRAY}>>. |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=cut |
374
|
|
|
|
|
|
|
sub derefOmicron { |
375
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
376
|
0
|
|
|
|
|
|
return $this->subtype->derefOmicron(); |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=item B |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
Get the hash type out of a glob type. This is roughly equivalent to C<<*foo{HASH}>>. |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=cut |
384
|
|
|
|
|
|
|
sub derefChi { |
385
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
386
|
0
|
|
|
|
|
|
return $this->subtype->derefChi(); |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=item B |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Get the CV type out of a glob type. This is roughly equivalent to C<<*foo{CODE}>>. |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=cut |
394
|
|
|
|
|
|
|
sub derefZeta { |
395
|
0
|
|
|
0
|
1
|
|
my ($this) = @_; |
396
|
0
|
|
|
|
|
|
return $this->subtype->derefZeta(); |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=item B |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
Coerce a hash in to an array. |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
=cut |
404
|
|
|
|
|
|
|
sub listCoerce { |
405
|
0
|
|
|
0
|
1
|
|
my ($this, $env) = @_; |
406
|
0
|
|
|
|
|
|
return $this->subtype->listCoerce($env); |
407
|
|
|
|
|
|
|
} |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=item B |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
Dereference the parameter list type from a CV. |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
=cut |
414
|
|
|
|
|
|
|
sub derefParam { |
415
|
0
|
|
|
0
|
1
|
|
my ($this, $env) = @_; |
416
|
0
|
|
|
|
|
|
return $this->subtype->derefParam(); |
417
|
|
|
|
|
|
|
} |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
=item B |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
Dereference the return value type from a CV. |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
=cut |
424
|
|
|
|
|
|
|
sub derefReturn { |
425
|
0
|
|
|
0
|
1
|
|
my ($this, $env) = @_; |
426
|
0
|
|
|
|
|
|
return $this->subtype->derefReturn(); |
427
|
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
=back |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
=cut |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
TRUE; |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
=head1 AUTHOR |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
Gary Jackson, C<< >> |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
=head1 BUGS |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
This version is specific to Perl 5.8.1. It may work with other |
442
|
|
|
|
|
|
|
versions that have the same opcode list and structure, but this is |
443
|
|
|
|
|
|
|
entirely untested. It definitely will not work if those parameters |
444
|
|
|
|
|
|
|
change. |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
Please report any bugs or feature requests to |
447
|
|
|
|
|
|
|
C, or through the web interface at |
448
|
|
|
|
|
|
|
L. |
449
|
|
|
|
|
|
|
I will be notified, and then you'll automatically be notified of progress on |
450
|
|
|
|
|
|
|
your bug as I make changes. |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
Copyright 2005 Gary Jackson, all rights reserved. |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
457
|
|
|
|
|
|
|
under the same terms as Perl itself. |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=cut |