line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Set::Array; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
47661
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
73
|
|
4
|
2
|
|
|
2
|
|
1941
|
use attributes qw(reftype); |
|
2
|
|
|
|
|
4077
|
|
|
2
|
|
|
|
|
11
|
|
5
|
2
|
|
|
2
|
|
2962
|
use subs qw(foreach pack push pop shift join rindex splice unpack unshift); |
|
2
|
|
|
|
|
52
|
|
|
2
|
|
|
|
|
12
|
|
6
|
|
|
|
|
|
|
|
7
|
2
|
|
|
2
|
|
2105
|
use Want; |
|
2
|
|
|
|
|
7603
|
|
|
2
|
|
|
|
|
213
|
|
8
|
2
|
|
|
2
|
|
26
|
use Carp; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
155
|
|
9
|
2
|
|
|
2
|
|
24864
|
use Try::Tiny; |
|
2
|
|
|
|
|
7737
|
|
|
2
|
|
|
|
|
8708
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
# Some not documented/implemented. Waiting for Want-0.06 to arrive. |
12
|
|
|
|
|
|
|
use overload |
13
|
2
|
|
|
|
|
1008
|
"==" => "is_equal", |
14
|
|
|
|
|
|
|
"!=" => "not_equal", |
15
|
|
|
|
|
|
|
"+" => "union", |
16
|
|
|
|
|
|
|
"&" => "bag", |
17
|
|
|
|
|
|
|
"*" => "intersection", |
18
|
|
|
|
|
|
|
"-" => "difference", |
19
|
|
|
|
|
|
|
"%" => "symmetric_difference", |
20
|
|
|
|
|
|
|
"<<" => "push", |
21
|
|
|
|
|
|
|
">>" => "shift", |
22
|
|
|
|
|
|
|
"<<=" => "unshift", |
23
|
|
|
|
|
|
|
">>=" => "pop", |
24
|
2
|
|
|
2
|
|
3017
|
"fallback" => 1; |
|
2
|
|
|
|
|
1127
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
our $VERSION = '0.30'; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub new{ |
29
|
23
|
|
|
23
|
1
|
7690
|
my($class,@array) = @_; |
30
|
23
|
50
|
33
|
|
|
68
|
@array = @$class if !@array && ref($class); |
31
|
23
|
|
33
|
|
|
128
|
return bless \@array, ref($class) || $class; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# Turn array into a hash |
35
|
|
|
|
|
|
|
sub as_hash{ |
36
|
6
|
|
|
6
|
1
|
22
|
my($self,$order,@arg) = @_; |
37
|
|
|
|
|
|
|
|
38
|
6
|
100
|
|
|
|
17
|
if (! defined $order) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
39
|
3
|
|
|
|
|
7
|
$order = 'even'; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
elsif (ref $order eq 'HASH') { |
42
|
1
|
|
|
|
|
2
|
$order = $$order{'key_option'}; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
elsif ($order eq 'key_option') { |
45
|
1
|
|
|
|
|
2
|
$order = $arg[0]; |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
6
|
|
|
|
|
9
|
$order = lc $order; |
49
|
|
|
|
|
|
|
|
50
|
6
|
50
|
|
|
|
23
|
if ($order =~ /^(?:odd|even)$/) { |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
else { |
53
|
0
|
|
|
|
|
0
|
Carp::croak "Unrecognized option ($order) passed to 'as_hash()' method"; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
6
|
|
|
|
|
7
|
my %hash; |
57
|
|
|
|
|
|
|
|
58
|
6
|
100
|
|
|
|
10
|
if($order eq 'odd') { |
59
|
3
|
|
|
|
|
74
|
%hash = CORE::reverse(@$self); |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
else { |
62
|
3
|
|
|
|
|
66
|
%hash = @$self; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
6
|
50
|
|
|
|
16
|
if(want('OBJECT')){ return $self } # This shouldn't happen |
|
0
|
|
|
|
|
0
|
|
66
|
|
|
|
|
|
|
|
67
|
6
|
100
|
|
|
|
272
|
return %hash if wantarray; |
68
|
1
|
|
|
|
|
4
|
return \%hash; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
*to_hash = \&as_hash; |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# Return element at specified index |
73
|
|
|
|
|
|
|
sub at{ |
74
|
3
|
|
|
3
|
1
|
29075
|
my($self,$index) = @_; |
75
|
3
|
50
|
|
|
|
16
|
if(want('OBJECT')){ return bless \${$self}[$index] } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
76
|
3
|
|
|
|
|
188
|
return @$self[$index]; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# Delete (or undef) contents of array |
80
|
|
|
|
|
|
|
sub clear{ |
81
|
2
|
|
|
2
|
1
|
5
|
my($self,$undef) = @_; |
82
|
2
|
100
|
|
|
|
6
|
if($undef){ @{$self} = map{ undef } @{$self} } |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
3
|
|
|
3
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
4
|
|
83
|
1
|
|
|
|
|
2
|
else{ @{$self} = () } |
|
1
|
|
|
|
|
3
|
|
84
|
|
|
|
|
|
|
|
85
|
2
|
50
|
|
|
|
7
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
86
|
2
|
50
|
|
|
|
82
|
if(wantarray){ return @$self } |
|
0
|
|
|
|
|
0
|
|
87
|
2
|
50
|
|
|
|
8
|
if(defined wantarray){ return \@{$self} } |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
8
|
|
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# Remove all undef elements. It can be chained. |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub compact{ |
93
|
2
|
|
|
2
|
1
|
7
|
my($self) = @_; |
94
|
|
|
|
|
|
|
|
95
|
2
|
100
|
66
|
|
|
7
|
if( (want('OBJECT')) || (!defined wantarray) ){ |
96
|
1
|
|
|
|
|
58
|
@$self = grep defined $_, @$self; |
97
|
1
|
|
|
|
|
3
|
return $self; |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
1
|
|
|
|
|
74
|
my @temp; |
101
|
1
|
100
|
|
|
|
2
|
CORE::foreach(@{$self}){ CORE::push(@temp,$_) if defined $_ } |
|
1
|
|
|
|
|
4
|
|
|
6
|
|
|
|
|
15
|
|
102
|
1
|
50
|
|
|
|
4
|
if(wantarray){ return @temp } |
|
0
|
|
|
|
|
0
|
|
103
|
1
|
50
|
|
|
|
6
|
if(defined wantarray){ return \@temp } |
|
1
|
|
|
|
|
5
|
|
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
# Return the number of times the specified value appears within array |
107
|
|
|
|
|
|
|
sub count{ |
108
|
4
|
|
|
4
|
1
|
443
|
my($self,$val) = @_; |
109
|
|
|
|
|
|
|
|
110
|
4
|
|
|
|
|
7
|
my $hits = 0; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# Count undefined elements |
113
|
4
|
50
|
|
|
|
17
|
unless(defined($val)){ |
114
|
0
|
0
|
|
|
|
0
|
foreach(@$self){ $hits++ unless $_ } |
|
0
|
|
|
|
|
0
|
|
115
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return bless \$hits } |
|
0
|
|
|
|
|
0
|
|
116
|
0
|
|
|
|
|
0
|
return $hits; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
4
|
|
|
|
|
90
|
$hits = grep /^\Q$val\E$/, @$self; |
120
|
4
|
50
|
|
|
|
14
|
if(want('OBJECT')){ return bless \$hits } |
|
0
|
|
|
|
|
0
|
|
121
|
4
|
|
|
|
|
173
|
return $hits; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# Pops and returns /the object/. I.e it can be chained. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub cpop{ |
127
|
4
|
|
|
4
|
1
|
15
|
my($self) = @_; |
128
|
4
|
|
|
|
|
4
|
my $popped = CORE::pop(@$self); |
129
|
4
|
|
|
|
|
8
|
return $self; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
# Shifts and returns /the object/. I.e it can be chained. |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub cshift{ |
135
|
4
|
|
|
4
|
1
|
12
|
my($self) = @_; |
136
|
4
|
|
|
|
|
5
|
my $shifted = CORE::shift @$self; |
137
|
4
|
|
|
|
|
11
|
return $self; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# Delete all instances of the specified value within the array. It can be chained. |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
sub delete{ |
143
|
3
|
|
|
3
|
1
|
13
|
my($self,@vals) = @_; |
144
|
|
|
|
|
|
|
|
145
|
3
|
50
|
|
|
|
10
|
unless(defined($vals[0])){ |
146
|
0
|
|
|
|
|
0
|
Carp::croak "Undefined value passed to 'delete()' method"; |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
3
|
|
|
|
|
5
|
foreach my $val(@vals){ |
150
|
3
|
|
|
|
|
113
|
@$self = grep $_ !~ /^\Q$val\E$/, @$self; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
3
|
50
|
|
|
|
14
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
154
|
3
|
50
|
|
|
|
152
|
if(wantarray){ return @$self } |
|
0
|
|
|
|
|
0
|
|
155
|
3
|
100
|
|
|
|
13
|
if(defined wantarray){ return \@$self } |
|
2
|
|
|
|
|
18
|
|
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Deletes an element at a specified index, or range of indices |
159
|
|
|
|
|
|
|
# I'm not sure I like the range behavior for this method and may change it |
160
|
|
|
|
|
|
|
# (or remove it) in the future. |
161
|
|
|
|
|
|
|
sub delete_at{ |
162
|
2
|
|
|
2
|
1
|
4
|
my($self,$start_index, $end_index) = @_; |
163
|
|
|
|
|
|
|
|
164
|
2
|
50
|
|
|
|
7
|
unless(defined($start_index)){ |
165
|
0
|
|
|
|
|
0
|
Carp::croak "No index passed to 'delete_at()' method"; |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
2
|
100
|
|
|
|
15
|
unless(defined($end_index)){ $end_index = 0 } |
|
1
|
|
|
|
|
4
|
|
169
|
2
|
50
|
33
|
|
|
15
|
if( ($end_index eq 'end') || ($end_index == -1) ){ $end_index = $#$self } |
|
0
|
|
|
|
|
0
|
|
170
|
|
|
|
|
|
|
|
171
|
2
|
|
|
|
|
4
|
my $num = ($end_index - $start_index) + 1; |
172
|
|
|
|
|
|
|
|
173
|
2
|
|
|
|
|
4
|
CORE::splice(@{$self},$start_index,$num); |
|
2
|
|
|
|
|
5
|
|
174
|
|
|
|
|
|
|
|
175
|
2
|
50
|
33
|
|
|
9
|
if(want('OBJECT') || !(defined wantarray)){ return $self } |
|
0
|
|
|
|
|
0
|
|
176
|
2
|
50
|
|
|
|
102
|
if(wantarray){ return @$self } |
|
0
|
|
|
|
|
0
|
|
177
|
2
|
50
|
|
|
|
7
|
if(defined wantarray){ return \@{$self} } |
|
2
|
|
|
|
|
10
|
|
|
2
|
|
|
|
|
9
|
|
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# Returns a list of duplicate items in the array. It can be chained. |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
sub duplicates{ |
183
|
2
|
|
|
2
|
1
|
608
|
my($self) = @_; |
184
|
|
|
|
|
|
|
|
185
|
2
|
|
|
|
|
2
|
my(@dups,%count); |
186
|
|
|
|
|
|
|
|
187
|
2
|
|
|
|
|
6
|
CORE::foreach(@$self){ |
188
|
12
|
|
|
|
|
21
|
$count{$_}++; |
189
|
12
|
100
|
|
|
|
27
|
if($count{$_} > 1){ CORE::push(@dups,$_) } |
|
4
|
|
|
|
|
8
|
|
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
2
|
50
|
33
|
|
|
8
|
if(want('OBJECT') || !(defined wantarray)){ |
193
|
0
|
|
|
|
|
0
|
@$self = @dups; |
194
|
0
|
|
|
|
|
0
|
return $self; |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
2
|
50
|
|
|
|
107
|
if(wantarray){ return @dups } |
|
2
|
|
|
|
|
11
|
|
198
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@dups } |
|
0
|
|
|
|
|
0
|
|
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
# Tests to see if value exists anywhere within array |
202
|
|
|
|
|
|
|
sub exists{ |
203
|
2
|
|
|
2
|
1
|
671
|
my($self,$val) = @_; |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
# Check specifically for undefined values |
206
|
2
|
50
|
|
|
|
7
|
unless(defined($val)){ |
207
|
0
|
0
|
|
|
|
0
|
foreach(@$self){ unless($_){ return 1 } } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
208
|
0
|
|
|
|
|
0
|
return 0; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
2
|
100
|
|
|
|
45
|
if(grep /^\Q$val\E$/, @$self){ return 1 } |
|
1
|
|
|
|
|
5
|
|
212
|
|
|
|
|
|
|
|
213
|
1
|
|
|
|
|
5
|
return 0; |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
*contains = \&exists; |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
# Fills the elements of the array. Does not create new elements |
219
|
|
|
|
|
|
|
sub fill{ |
220
|
2
|
|
|
2
|
1
|
10
|
my($self,$val, $start, $length) = @_; # Start may also be a range |
221
|
2
|
50
|
|
|
|
3
|
return unless(scalar(@{$self}) > 0); # Test for empty array |
|
2
|
|
|
|
|
8
|
|
222
|
|
|
|
|
|
|
|
223
|
2
|
100
|
|
|
|
5
|
unless(defined($start)){ $start = 0 } |
|
1
|
|
|
|
|
1
|
|
224
|
|
|
|
|
|
|
|
225
|
2
|
50
|
|
|
|
6
|
if($length){ $length += $start } |
|
0
|
|
|
|
|
0
|
|
226
|
2
|
|
|
|
|
5
|
else{ $length = $#$self + 1} |
227
|
|
|
|
|
|
|
|
228
|
2
|
100
|
|
|
|
12
|
if($start =~ /^(\d+)\.\.(\d+)$/){ |
229
|
1
|
|
|
|
|
8
|
CORE::foreach($1..$2){ @{$self}[$_] = $val } |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
6
|
|
230
|
1
|
|
|
|
|
8
|
return $self; |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
|
233
|
1
|
|
|
|
|
4
|
CORE::foreach(my $n=$start; $n<$length; $n++){ @{$self}[$n] = $val } |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
19
|
|
234
|
|
|
|
|
|
|
|
235
|
1
|
50
|
|
|
|
4
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
236
|
1
|
50
|
|
|
|
52
|
if(wantarray){ return @$self } |
|
0
|
|
|
|
|
0
|
|
237
|
1
|
50
|
|
|
|
6
|
if(defined wantarray){ return \@{$self} } |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
5
|
|
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
# Returns the first element of the array |
241
|
|
|
|
|
|
|
sub first{ |
242
|
1
|
|
|
1
|
1
|
993
|
my($self) = @_; |
243
|
1
|
50
|
|
|
|
6
|
if(want('OBJECT')){ return bless \@{$self}[0] } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
244
|
1
|
|
|
|
|
62
|
return @{$self}[0]; |
|
1
|
|
|
|
|
6
|
|
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
# Flattens any list references into a plain list |
248
|
|
|
|
|
|
|
sub flatten{ |
249
|
1
|
|
|
1
|
1
|
2
|
my($self) = @_; |
250
|
|
|
|
|
|
|
|
251
|
1
|
50
|
33
|
|
|
4
|
if( (want('OBJECT')) || (!defined wantarray) ){ |
252
|
0
|
|
|
|
|
0
|
for(my $n=0; $n<=$#$self; $n++){ |
253
|
0
|
0
|
|
|
|
0
|
if( ref($$self[$n]) eq 'ARRAY' ){ |
254
|
0
|
|
|
|
|
0
|
CORE::splice(@$self,$n,1,@{$$self[$n]}); |
|
0
|
|
|
|
|
0
|
|
255
|
0
|
|
|
|
|
0
|
$n--; |
256
|
0
|
|
|
|
|
0
|
next; |
257
|
|
|
|
|
|
|
} |
258
|
0
|
0
|
|
|
|
0
|
if( ref($$self[$n]) eq 'HASH' ){ |
259
|
0
|
|
|
|
|
0
|
CORE::splice(@$self,$n,1,%{$$self[$n]}); |
|
0
|
|
|
|
|
0
|
|
260
|
0
|
|
|
|
|
0
|
--$n; |
261
|
0
|
|
|
|
|
0
|
next; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
} |
264
|
0
|
|
|
|
|
0
|
return $self |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
1
|
|
|
|
|
54
|
my @temp = @$self; |
268
|
1
|
|
|
|
|
6
|
for(my $n=0; $n<=$#temp; $n++){ |
269
|
8
|
100
|
|
|
|
17
|
if( ref($temp[$n]) eq 'ARRAY' ){ |
270
|
2
|
|
|
|
|
4
|
CORE::splice(@temp,$n,1,@{$temp[$n]}); |
|
2
|
|
|
|
|
8
|
|
271
|
2
|
|
|
|
|
2
|
$n--; |
272
|
2
|
|
|
|
|
6
|
next; |
273
|
|
|
|
|
|
|
} |
274
|
6
|
50
|
|
|
|
18
|
if( ref($temp[$n]) eq 'HASH' ){ |
275
|
0
|
|
|
|
|
0
|
CORE::splice(@temp,$n,1,%{$temp[$n]}); |
|
0
|
|
|
|
|
0
|
|
276
|
0
|
|
|
|
|
0
|
--$n; |
277
|
0
|
|
|
|
|
0
|
next; |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
} |
280
|
1
|
50
|
|
|
|
11
|
if(wantarray){ return @temp } |
|
1
|
|
|
|
|
6
|
|
281
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@temp } |
|
0
|
|
|
|
|
0
|
|
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
# Loop mechanism |
285
|
|
|
|
|
|
|
sub foreach{ |
286
|
1
|
|
|
1
|
|
645
|
my($self,$coderef) = @_; |
287
|
|
|
|
|
|
|
|
288
|
1
|
50
|
|
|
|
7
|
unless(ref($coderef) eq 'CODE'){ |
289
|
0
|
|
|
|
|
0
|
Carp::croak "Invalid code reference passed to 'foreach' method"; |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
1
|
|
|
|
|
3
|
CORE::foreach (@$self){ &$coderef } |
|
5
|
|
|
|
|
18
|
|
293
|
|
|
|
|
|
|
|
294
|
1
|
50
|
|
|
|
6
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
295
|
1
|
50
|
|
|
|
48
|
if(wantarray){ return @$self } |
|
0
|
|
|
|
|
0
|
|
296
|
1
|
50
|
|
|
|
6
|
if(defined wantarray){ return \@{$self} } |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
297
|
|
|
|
|
|
|
} |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
# Append or prepend a string to each element of the array |
300
|
|
|
|
|
|
|
sub impose{ |
301
|
0
|
|
|
0
|
1
|
0
|
my($self,$placement,$string) = @_; |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
# Set defaults |
304
|
0
|
0
|
|
|
|
0
|
unless($placement =~ /\bappend\b|\bprepend\b/i){ |
305
|
0
|
|
|
|
|
0
|
$string = $placement; |
306
|
0
|
|
|
|
|
0
|
$placement = 'append'; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
|
309
|
0
|
0
|
|
|
|
0
|
unless(CORE::defined($string)){ |
310
|
0
|
|
|
|
|
0
|
Carp::croak "No string supplied to 'impose()' method"; |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
0
|
0
|
0
|
|
|
0
|
if(want('OBJECT') or !(defined wantarray)){ |
314
|
0
|
0
|
|
|
|
0
|
if($placement =~ /append/){ foreach(@$self){ $_ = $_ . $string } } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
315
|
0
|
0
|
|
|
|
0
|
if($placement =~ /prepend/){ foreach(@$self){ $_ = $string . $_ } } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
316
|
0
|
|
|
|
|
0
|
return $self; |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
0
|
|
|
|
|
0
|
my @copy = @$self; |
320
|
0
|
0
|
|
|
|
0
|
if($placement =~ /append/){ foreach(@copy){ $_ = $_ . $string } } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
321
|
0
|
0
|
|
|
|
0
|
if($placement =~ /prepend/){ foreach(@copy){ $_ = $string . $_ } } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
322
|
|
|
|
|
|
|
|
323
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @copy } |
|
0
|
|
|
|
|
0
|
|
324
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@copy } |
|
0
|
|
|
|
|
0
|
|
325
|
|
|
|
|
|
|
} |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
# Returns the index of the first occurrence within the array |
328
|
|
|
|
|
|
|
# of the specified value |
329
|
|
|
|
|
|
|
sub index{ |
330
|
1
|
|
|
1
|
1
|
228
|
my($self,$val) = @_; |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
# Test for undefined value |
333
|
1
|
50
|
|
|
|
3
|
unless(defined($val)){ |
334
|
0
|
|
|
|
|
0
|
for(my $n=0; $n<=$#$self; $n++){ |
335
|
0
|
0
|
|
|
|
0
|
unless($self->[$n]){ |
336
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return bless \$n } |
|
0
|
|
|
|
|
0
|
|
337
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return $n } |
|
0
|
|
|
|
|
0
|
|
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
1
|
|
|
|
|
4
|
for(my $n=0; $n<=$#$self; $n++){ |
343
|
1
|
50
|
|
|
|
3
|
next unless defined $self->[$n]; |
344
|
1
|
50
|
|
|
|
12
|
if( $self->[$n] =~ /^\Q$val\E$/ ){ |
345
|
1
|
50
|
|
|
|
51
|
if(want('OBJECT')){ return bless \$n } |
|
0
|
|
|
|
|
0
|
|
346
|
1
|
50
|
|
|
|
48
|
if(defined wantarray){ return $n } |
|
1
|
|
|
|
|
3
|
|
347
|
|
|
|
|
|
|
} |
348
|
|
|
|
|
|
|
} |
349
|
0
|
|
|
|
|
0
|
return undef; |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
# Given an index, or range of indices, returns the value at that index |
353
|
|
|
|
|
|
|
# (or a list of values for a range). |
354
|
|
|
|
|
|
|
sub indices{ |
355
|
1
|
|
|
1
|
1
|
63
|
my($self,@indices) = @_; |
356
|
1
|
|
|
|
|
2
|
my @iArray; |
357
|
|
|
|
|
|
|
|
358
|
1
|
50
|
|
|
|
36
|
unless(defined($indices[0])){ |
359
|
0
|
|
|
|
|
0
|
Carp::croak "No index/indices passed to 'indices' (aka 'get') method"; |
360
|
|
|
|
|
|
|
} |
361
|
|
|
|
|
|
|
|
362
|
1
|
|
|
|
|
4
|
CORE::foreach(@indices){ |
363
|
1
|
50
|
|
|
|
9
|
if($_ =~ /(\d+)\.\.(\d+)/){ for($1..$2){ |
|
1
|
|
|
|
|
6
|
|
364
|
3
|
|
|
|
|
4
|
CORE::push(@iArray,@{$self}[$_]) }; |
|
3
|
|
|
|
|
9
|
|
365
|
1
|
|
|
|
|
3
|
next; |
366
|
|
|
|
|
|
|
} |
367
|
0
|
0
|
|
|
|
0
|
if(@{$self}[$_]){ CORE::push(@iArray,@{$self}[$_]) } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
368
|
0
|
|
|
|
|
0
|
else{ CORE::push(@iArray,undef) } |
369
|
|
|
|
|
|
|
} |
370
|
|
|
|
|
|
|
|
371
|
1
|
50
|
|
|
|
12
|
if(scalar(@iArray) == 1){ |
372
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return bless \$iArray[0] } |
|
0
|
|
|
|
|
0
|
|
373
|
0
|
|
|
|
|
0
|
return $iArray[0]; |
374
|
|
|
|
|
|
|
} |
375
|
|
|
|
|
|
|
|
376
|
1
|
50
|
|
|
|
5
|
if(want('OBJECT')){ return bless \@iArray } |
|
1
|
|
|
|
|
55
|
|
377
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @iArray } |
|
0
|
|
|
|
|
0
|
|
378
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@iArray } |
|
0
|
|
|
|
|
0
|
|
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
# Alias for 'indices()' |
382
|
|
|
|
|
|
|
*get = \&indices; |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
# Tests to see if array contains any elements |
385
|
|
|
|
|
|
|
sub is_empty{ |
386
|
0
|
|
|
0
|
1
|
0
|
my($self) = @_; |
387
|
0
|
0
|
|
|
|
0
|
if( (scalar @{$self}) > 0){ return 0 } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
388
|
0
|
|
|
|
|
0
|
return 1; |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
# Set a specific index to a specific value |
392
|
|
|
|
|
|
|
sub set{ |
393
|
0
|
|
|
0
|
1
|
0
|
my($self,$index,$val) = @_; |
394
|
|
|
|
|
|
|
|
395
|
0
|
0
|
0
|
|
|
0
|
unless(defined($index) && $val){ |
396
|
0
|
|
|
|
|
0
|
Carp::croak "No index or value passed to 'set()' method"; |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ |
400
|
0
|
|
|
|
|
0
|
$self->[$index] = $val; |
401
|
0
|
|
|
|
|
0
|
return $self; |
402
|
|
|
|
|
|
|
} |
403
|
|
|
|
|
|
|
|
404
|
0
|
|
|
|
|
0
|
my @copy = @$self; |
405
|
0
|
|
|
|
|
0
|
$copy[$index] = $val; |
406
|
|
|
|
|
|
|
|
407
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @copy } |
|
0
|
|
|
|
|
0
|
|
408
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@copy } |
|
0
|
|
|
|
|
0
|
|
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
# Joins the contents of the list with the specified string |
412
|
|
|
|
|
|
|
sub join{ |
413
|
5
|
|
|
5
|
|
21
|
my($self,$s) = @_; |
414
|
|
|
|
|
|
|
|
415
|
5
|
50
|
|
|
|
12
|
$s = ',' unless $s; |
416
|
|
|
|
|
|
|
|
417
|
5
|
|
|
|
|
7
|
my $string; |
418
|
|
|
|
|
|
|
|
419
|
5
|
50
|
|
|
|
15
|
if(want('OBJECT')){ |
420
|
5
|
|
|
|
|
602
|
$string = CORE::join($s,@$self); |
421
|
5
|
|
|
|
|
24
|
return bless \$string; |
422
|
|
|
|
|
|
|
} |
423
|
|
|
|
|
|
|
|
424
|
0
|
|
|
|
|
0
|
$string = CORE::join($s,@$self); |
425
|
0
|
|
|
|
|
0
|
return $string; |
426
|
|
|
|
|
|
|
} |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
# Returns the last element of the array |
429
|
|
|
|
|
|
|
sub last{ |
430
|
0
|
|
|
0
|
1
|
0
|
my($self) = @_; |
431
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return bless \@{$self}[-1] } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
432
|
0
|
|
|
|
|
0
|
return @$self[-1]; |
433
|
|
|
|
|
|
|
} |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
# Returns the number of elements within the array |
436
|
|
|
|
|
|
|
sub length{ |
437
|
5
|
|
|
5
|
1
|
16368
|
my($self) = @_; |
438
|
5
|
|
|
|
|
9
|
my $length = scalar(@$self); |
439
|
5
|
50
|
|
|
|
18
|
if(want('OBJECT')){ return bless \$length } |
|
0
|
|
|
|
|
0
|
|
440
|
5
|
|
|
|
|
244
|
return $length; |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
# Returns the maximum numerical value in the array |
444
|
|
|
|
|
|
|
sub max{ |
445
|
0
|
|
|
0
|
1
|
0
|
my($self) = @_; |
446
|
0
|
|
|
|
|
0
|
my $max; |
447
|
|
|
|
|
|
|
|
448
|
2
|
|
|
2
|
|
12910
|
no warnings 'uninitialized'; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
2471
|
|
449
|
0
|
0
|
|
|
|
0
|
CORE::foreach(@{$self}){ $max = $_ if $_ > $max } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
450
|
|
|
|
|
|
|
|
451
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return bless \$max } |
|
0
|
|
|
|
|
0
|
|
452
|
0
|
|
|
|
|
0
|
return $max; |
453
|
|
|
|
|
|
|
} |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
sub pack{ |
456
|
0
|
|
|
0
|
|
0
|
my($self,$template) = @_; |
457
|
|
|
|
|
|
|
|
458
|
0
|
0
|
|
|
|
0
|
Carp::croak "No template provided to 'pack()' method" unless $template; |
459
|
|
|
|
|
|
|
|
460
|
0
|
0
|
0
|
|
|
0
|
if(want('OBJECT') || !(defined wantarray)){ |
461
|
0
|
|
|
|
|
0
|
$self->[0] = CORE::pack($template, @$self); |
462
|
0
|
|
|
|
|
0
|
$#$self = 0; |
463
|
0
|
|
|
|
|
0
|
return $self; |
464
|
|
|
|
|
|
|
} |
465
|
|
|
|
|
|
|
|
466
|
0
|
|
|
|
|
0
|
return CORE::pack($template,@$self); |
467
|
|
|
|
|
|
|
} |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
# Pops and returns the last element off the array |
470
|
|
|
|
|
|
|
sub pop{ |
471
|
0
|
|
|
0
|
|
0
|
my($self) = @_; |
472
|
0
|
|
|
|
|
0
|
my $popped = CORE::pop(@$self); |
473
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return bless \$popped } |
|
0
|
|
|
|
|
0
|
|
474
|
0
|
|
|
|
|
0
|
return $popped; |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
# Prints the contents of the array as a flat list. Optional newline |
478
|
|
|
|
|
|
|
sub print{ |
479
|
6
|
|
|
6
|
1
|
16
|
my($self,$nl) = @_; |
480
|
|
|
|
|
|
|
|
481
|
6
|
100
|
|
|
|
42
|
if(reftype($self) eq 'ARRAY'){ |
|
|
50
|
|
|
|
|
|
482
|
1
|
50
|
|
|
|
5
|
if(wantarray){ return @$self } |
|
1
|
|
|
|
|
6
|
|
483
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@{$self} } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
484
|
0
|
|
|
|
|
0
|
CORE::print @$self; |
485
|
0
|
0
|
|
|
|
0
|
if($nl){ CORE::print "\n" } |
|
0
|
|
|
|
|
0
|
|
486
|
|
|
|
|
|
|
} |
487
|
|
|
|
|
|
|
elsif(reftype($self) eq 'SCALAR'){ |
488
|
5
|
50
|
|
|
|
12
|
if(defined wantarray){ return $$self } |
|
5
|
|
|
|
|
19
|
|
489
|
0
|
|
|
|
|
0
|
CORE::print $$self; |
490
|
0
|
0
|
|
|
|
0
|
if($nl){ CORE::print "\n" } |
|
0
|
|
|
|
|
0
|
|
491
|
|
|
|
|
|
|
} |
492
|
|
|
|
|
|
|
else{ |
493
|
0
|
|
|
|
|
0
|
CORE::print @$self; |
494
|
0
|
0
|
|
|
|
0
|
if($nl){ CORE::print "\n" } |
|
0
|
|
|
|
|
0
|
|
495
|
|
|
|
|
|
|
} |
496
|
0
|
|
|
|
|
0
|
return $self; |
497
|
|
|
|
|
|
|
} |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
# Pushes an element onto the end of the array |
500
|
|
|
|
|
|
|
sub push{ |
501
|
0
|
|
|
0
|
|
0
|
my($self,@list) = @_; |
502
|
|
|
|
|
|
|
|
503
|
0
|
|
|
|
|
0
|
CORE::push(@{$self},@list); |
|
0
|
|
|
|
|
0
|
|
504
|
|
|
|
|
|
|
|
505
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
506
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @$self } |
|
0
|
|
|
|
|
0
|
|
507
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@{$self} }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
508
|
|
|
|
|
|
|
} |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
# Randomizes the order of the contents of the array |
511
|
|
|
|
|
|
|
# Taken from "The Perl Cookbook" |
512
|
|
|
|
|
|
|
sub randomize{ |
513
|
0
|
|
|
0
|
1
|
0
|
my($self) = @_; |
514
|
0
|
|
|
|
|
0
|
my($i,$ref,@temp); |
515
|
|
|
|
|
|
|
|
516
|
0
|
0
|
0
|
|
|
0
|
unless( (want('OBJECT')) || (!defined wantarray) ){ |
517
|
0
|
|
|
|
|
0
|
@temp = @{$self}; |
|
0
|
|
|
|
|
0
|
|
518
|
0
|
|
|
|
|
0
|
$ref = \@temp; |
519
|
|
|
|
|
|
|
} |
520
|
0
|
|
|
|
|
0
|
else{ $ref = $self } |
521
|
|
|
|
|
|
|
|
522
|
0
|
|
|
|
|
0
|
for($i = @$ref; --$i; ){ |
523
|
0
|
|
|
|
|
0
|
my $j = int rand ($i+1); |
524
|
0
|
0
|
|
|
|
0
|
next if $i == $j; |
525
|
0
|
|
|
|
|
0
|
@$ref[$i,$j] = @$ref[$j,$i]; |
526
|
|
|
|
|
|
|
} |
527
|
|
|
|
|
|
|
|
528
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
529
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @temp } |
|
0
|
|
|
|
|
0
|
|
530
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@temp } |
|
0
|
|
|
|
|
0
|
|
531
|
|
|
|
|
|
|
} |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
# Reverses the contents of the array |
534
|
|
|
|
|
|
|
sub reverse{ |
535
|
1
|
|
|
1
|
1
|
3
|
my($self) = @_; |
536
|
|
|
|
|
|
|
|
537
|
1
|
50
|
33
|
|
|
3
|
if( (want('OBJECT')) || (!defined wantarray) ){ |
538
|
0
|
|
|
|
|
0
|
@$self = CORE::reverse @$self; |
539
|
0
|
|
|
|
|
0
|
return $self; |
540
|
|
|
|
|
|
|
} |
541
|
|
|
|
|
|
|
|
542
|
1
|
|
|
|
|
43
|
my @temp = CORE::reverse @$self; |
543
|
1
|
50
|
|
|
|
3
|
if(wantarray){ return @temp } |
|
1
|
|
|
|
|
6
|
|
544
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@temp } |
|
0
|
|
|
|
|
0
|
|
545
|
|
|
|
|
|
|
} |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
# Same as index, except that it returns the position of the |
548
|
|
|
|
|
|
|
# last occurrence, instead of the first. |
549
|
|
|
|
|
|
|
sub rindex{ |
550
|
2
|
|
|
2
|
|
490
|
my($self,$val) = @_; |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
# Test for undefined value |
553
|
2
|
50
|
|
|
|
7
|
unless(defined($val)){ |
554
|
0
|
|
|
|
|
0
|
for(my $n = $#$self; $n >= 0; $n--){ |
555
|
0
|
0
|
|
|
|
0
|
unless($self->[$n]){ |
556
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return bless \$n } |
|
0
|
|
|
|
|
0
|
|
557
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return $n } |
|
0
|
|
|
|
|
0
|
|
558
|
|
|
|
|
|
|
} |
559
|
|
|
|
|
|
|
} |
560
|
|
|
|
|
|
|
} |
561
|
|
|
|
|
|
|
|
562
|
2
|
|
|
|
|
7
|
for(my $n = $#$self; $n >= 0; $n--){ |
563
|
5
|
50
|
|
|
|
20
|
next unless defined $self->[$n]; |
564
|
5
|
100
|
|
|
|
45
|
if( $self->[$n] =~ /^\Q$val\E$/ ){ |
565
|
1
|
50
|
|
|
|
4
|
if(want('OBJECT')){ return bless \$n } |
|
0
|
|
|
|
|
0
|
|
566
|
1
|
50
|
|
|
|
69
|
if(defined wantarray){ return $n } |
|
1
|
|
|
|
|
5
|
|
567
|
|
|
|
|
|
|
} |
568
|
|
|
|
|
|
|
} |
569
|
1
|
|
|
|
|
4
|
return undef; |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
} |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
# Moves the last element of the array to the front, or vice-versa |
574
|
|
|
|
|
|
|
sub rotate{ |
575
|
0
|
|
|
0
|
1
|
0
|
my($self,$dir) = @_; |
576
|
|
|
|
|
|
|
|
577
|
0
|
0
|
0
|
|
|
0
|
if( (want('OBJECT')) || (!defined wantarray) ){ |
578
|
0
|
0
|
0
|
|
|
0
|
unless(defined($dir) && $dir eq 'ftol'){ |
579
|
0
|
|
|
|
|
0
|
CORE::unshift(@$self, CORE::pop(@$self)); |
580
|
0
|
|
|
|
|
0
|
return $self; |
581
|
|
|
|
|
|
|
} |
582
|
0
|
|
|
|
|
0
|
CORE::push(@$self,CORE::shift(@$self)); |
583
|
0
|
|
|
|
|
0
|
return $self; |
584
|
|
|
|
|
|
|
} |
585
|
|
|
|
|
|
|
|
586
|
0
|
|
|
|
|
0
|
my @temp = @$self; |
587
|
0
|
0
|
0
|
|
|
0
|
unless(defined($dir) && $dir eq 'ftol'){ |
588
|
0
|
|
|
|
|
0
|
CORE::unshift(@temp, CORE::pop(@temp)); |
589
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @temp } |
|
0
|
|
|
|
|
0
|
|
590
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@temp } |
|
0
|
|
|
|
|
0
|
|
591
|
|
|
|
|
|
|
} |
592
|
0
|
|
|
|
|
0
|
CORE::push(@temp,CORE::shift(@temp)); |
593
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @temp } |
|
0
|
|
|
|
|
0
|
|
594
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@temp } |
|
0
|
|
|
|
|
0
|
|
595
|
|
|
|
|
|
|
} |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
# Shifts and returns the first element off the array |
598
|
|
|
|
|
|
|
sub shift{ |
599
|
0
|
|
|
0
|
|
0
|
my($self) = @_; |
600
|
0
|
|
|
|
|
0
|
my $shifted = CORE::shift @$self; |
601
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return bless \$shifted } |
|
0
|
|
|
|
|
0
|
|
602
|
0
|
|
|
|
|
0
|
return $shifted; |
603
|
|
|
|
|
|
|
} |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
# Sorts the array alphabetically. |
606
|
|
|
|
|
|
|
sub sort{ |
607
|
0
|
|
|
0
|
1
|
0
|
my($self,$coderef) = @_; |
608
|
|
|
|
|
|
|
|
609
|
0
|
0
|
|
|
|
0
|
if($coderef){ |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
# Complements of Sean McAfee |
612
|
0
|
|
|
|
|
0
|
my $caller = caller(); |
613
|
0
|
|
|
|
|
0
|
local(*a,*b) = do{ |
614
|
2
|
|
|
2
|
|
13
|
no strict 'refs'; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
445
|
|
615
|
0
|
|
|
|
|
0
|
(*{"${caller}::a"},*{"${caller}::b"}); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
616
|
|
|
|
|
|
|
}; |
617
|
|
|
|
|
|
|
|
618
|
0
|
0
|
0
|
|
|
0
|
if( (want('OBJECT')) || (!defined wantarray) ){ |
619
|
0
|
|
|
|
|
0
|
@$self = CORE::sort $coderef @$self; |
620
|
0
|
|
|
|
|
0
|
return $self; |
621
|
|
|
|
|
|
|
} |
622
|
|
|
|
|
|
|
|
623
|
0
|
|
|
|
|
0
|
my @sorted = CORE::sort $coderef @$self; |
624
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @sorted } |
|
0
|
|
|
|
|
0
|
|
625
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@sorted } |
|
0
|
|
|
|
|
0
|
|
626
|
|
|
|
|
|
|
} |
627
|
|
|
|
|
|
|
else{ |
628
|
0
|
0
|
0
|
|
|
0
|
if( (want('OBJECT')) || (!defined wantarray) ){ |
629
|
0
|
|
|
|
|
0
|
@$self = CORE::sort @$self; |
630
|
0
|
|
|
|
|
0
|
return $self; |
631
|
|
|
|
|
|
|
} |
632
|
0
|
|
|
|
|
0
|
my @sorted = CORE::sort @$self; |
633
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @sorted } |
|
0
|
|
|
|
|
0
|
|
634
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@sorted } |
|
0
|
|
|
|
|
0
|
|
635
|
|
|
|
|
|
|
} |
636
|
|
|
|
|
|
|
} |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
# Splices a value, or range of values, from the array |
639
|
|
|
|
|
|
|
sub splice{ |
640
|
0
|
|
|
0
|
|
0
|
my($self,$offset,$length,@list) = @_; |
641
|
|
|
|
|
|
|
|
642
|
2
|
|
|
2
|
|
26
|
no warnings 'uninitialized'; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
3577
|
|
643
|
|
|
|
|
|
|
|
644
|
0
|
|
|
|
|
0
|
my @deleted; |
645
|
0
|
0
|
|
|
|
0
|
unless(defined($offset)){ |
646
|
0
|
|
|
|
|
0
|
@deleted = CORE::splice(@$self); |
647
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
648
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @deleted } |
|
0
|
|
|
|
|
0
|
|
649
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@deleted } |
|
0
|
|
|
|
|
0
|
|
650
|
|
|
|
|
|
|
} |
651
|
0
|
0
|
|
|
|
0
|
unless(defined($length)){ |
652
|
0
|
|
|
|
|
0
|
@deleted = CORE::splice(@$self,$offset); |
653
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
654
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @deleted } |
|
0
|
|
|
|
|
0
|
|
655
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@deleted } |
|
0
|
|
|
|
|
0
|
|
656
|
|
|
|
|
|
|
} |
657
|
0
|
0
|
|
|
|
0
|
unless(defined($list[0])){ |
658
|
0
|
|
|
|
|
0
|
@deleted = CORE::splice(@$self,$offset,$length); |
659
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
660
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @deleted } |
|
0
|
|
|
|
|
0
|
|
661
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@deleted } |
|
0
|
|
|
|
|
0
|
|
662
|
|
|
|
|
|
|
} |
663
|
|
|
|
|
|
|
|
664
|
0
|
|
|
|
|
0
|
@deleted = CORE::splice(@$self,$offset,$length,@list); |
665
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
666
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @deleted } |
|
0
|
|
|
|
|
0
|
|
667
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@deleted } |
|
0
|
|
|
|
|
0
|
|
668
|
|
|
|
|
|
|
} |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
# Returns a list of unique items in the array. It can be chained. |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
sub unique{ |
673
|
3
|
|
|
3
|
1
|
6
|
my($self) = @_; |
674
|
|
|
|
|
|
|
|
675
|
3
|
|
|
|
|
6
|
my %item; |
676
|
|
|
|
|
|
|
|
677
|
3
|
|
|
|
|
9
|
CORE::foreach(@$self){ $item{$_}++ } |
|
18
|
|
|
|
|
32
|
|
678
|
|
|
|
|
|
|
|
679
|
3
|
100
|
66
|
|
|
10
|
if(want('OBJECT') || !(defined wantarray)){ |
680
|
1
|
|
|
|
|
50
|
@$self = keys %item; |
681
|
1
|
|
|
|
|
6
|
return $self; |
682
|
|
|
|
|
|
|
} |
683
|
|
|
|
|
|
|
|
684
|
2
|
|
|
|
|
92
|
my @temp = keys %item; |
685
|
|
|
|
|
|
|
|
686
|
2
|
100
|
|
|
|
8
|
if(wantarray){ return @temp } |
|
1
|
|
|
|
|
7
|
|
687
|
1
|
50
|
|
|
|
24
|
if(defined wantarray){ return \@temp } |
|
1
|
|
|
|
|
4
|
|
688
|
|
|
|
|
|
|
} |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
# Unshifts a value to the front of the array |
691
|
|
|
|
|
|
|
sub unshift{ |
692
|
0
|
|
|
0
|
|
0
|
my($self,@list) = @_; |
693
|
0
|
|
|
|
|
0
|
CORE::unshift(@$self,@list); |
694
|
|
|
|
|
|
|
|
695
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return $self } |
|
0
|
|
|
|
|
0
|
|
696
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @$self } |
|
0
|
|
|
|
|
0
|
|
697
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@{$self} }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
698
|
|
|
|
|
|
|
} |
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
#### OVERLOADED OPERATOR METHODS #### |
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
# Really just a 'push', but needs to handle ops |
703
|
|
|
|
|
|
|
sub append{ |
704
|
0
|
|
|
0
|
0
|
0
|
my($op1, $op2, $reversed) = @_; |
705
|
0
|
0
|
|
|
|
0
|
($op2,$op1) = ($op1,$op2) if $reversed; |
706
|
|
|
|
|
|
|
|
707
|
0
|
|
|
|
|
0
|
CORE::push(@{$op1},@{$op2}); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
708
|
|
|
|
|
|
|
|
709
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return $op1 } |
|
0
|
|
|
|
|
0
|
|
710
|
0
|
0
|
|
|
|
0
|
return @$op1 if wantarray; |
711
|
0
|
0
|
|
|
|
0
|
return \@{$op1} if defined wantarray; |
|
0
|
|
|
|
|
0
|
|
712
|
|
|
|
|
|
|
} |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
# A union that includes non-unique values (i.e. everything) |
715
|
|
|
|
|
|
|
sub bag{ |
716
|
0
|
|
|
0
|
1
|
0
|
my($op1, $op2, $reversed) = @_; |
717
|
0
|
0
|
|
|
|
0
|
($op2,$op1) = ($op1,$op2) if $reversed; |
718
|
|
|
|
|
|
|
|
719
|
0
|
0
|
0
|
|
|
0
|
if(want('OBJECT') || !(defined wantarray)){ |
720
|
0
|
|
|
|
|
0
|
CORE::push(@$op1,@$op2); |
721
|
0
|
|
|
|
|
0
|
return $op1; |
722
|
|
|
|
|
|
|
} |
723
|
0
|
|
|
|
|
0
|
my @copy = (@$op1,@$op2); |
724
|
0
|
0
|
|
|
|
0
|
return @copy if wantarray; |
725
|
0
|
0
|
|
|
|
0
|
return \@copy if defined wantarray; |
726
|
|
|
|
|
|
|
} |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
# Needs work |
729
|
|
|
|
|
|
|
sub complement{ |
730
|
0
|
|
|
0
|
0
|
0
|
my($op1, $op2, $reversed) = @_; |
731
|
0
|
0
|
|
|
|
0
|
($op2,$op1) = ($op1,$op2) if $reversed; |
732
|
|
|
|
|
|
|
|
733
|
0
|
|
|
|
|
0
|
my(%item1,%item2,@comp); |
734
|
0
|
|
|
|
|
0
|
CORE::foreach(@$op1){ $item1{$_}++ } |
|
0
|
|
|
|
|
0
|
|
735
|
0
|
|
|
|
|
0
|
CORE::foreach(@$op2){ $item2{$_}++ } |
|
0
|
|
|
|
|
0
|
|
736
|
|
|
|
|
|
|
|
737
|
0
|
|
|
|
|
0
|
CORE::foreach(keys %item2){ |
738
|
0
|
0
|
|
|
|
0
|
if($item1{$_}){ next } |
|
0
|
|
|
|
|
0
|
|
739
|
0
|
|
|
|
|
0
|
CORE::push(@comp,$_); |
740
|
|
|
|
|
|
|
} |
741
|
|
|
|
|
|
|
|
742
|
0
|
0
|
|
|
|
0
|
if(want('OBJECT')){ return bless \@comp } |
|
0
|
|
|
|
|
0
|
|
743
|
0
|
0
|
|
|
|
0
|
if(wantarray){ return @comp } |
|
0
|
|
|
|
|
0
|
|
744
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@comp } |
|
0
|
|
|
|
|
0
|
|
745
|
|
|
|
|
|
|
} |
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
# Returns elements in left set that are not in the right set |
748
|
|
|
|
|
|
|
sub difference{ |
749
|
1
|
|
|
1
|
1
|
7
|
my($op1, $op2, $reversed) = @_; |
750
|
1
|
50
|
|
|
|
3
|
($op2,$op1) = ($op1,$op2) if $reversed; |
751
|
|
|
|
|
|
|
|
752
|
1
|
|
|
|
|
2
|
my(%item1,%item2,@diff); |
753
|
1
|
|
|
|
|
4
|
CORE::foreach(@$op1){ $item1{$_}=$_ } |
|
8
|
|
|
|
|
92
|
|
754
|
1
|
|
|
|
|
10
|
CORE::foreach(@$op2){ $item2{$_}=$_ } |
|
3
|
|
|
|
|
16
|
|
755
|
|
|
|
|
|
|
|
756
|
1
|
|
|
|
|
10
|
CORE::foreach(keys %item1){ |
757
|
8
|
100
|
|
|
|
17
|
if(exists $item2{$_}){ next } |
|
3
|
|
|
|
|
5
|
|
758
|
5
|
|
|
|
|
9
|
CORE::push(@diff,$item1{$_}); |
759
|
|
|
|
|
|
|
} |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
try |
762
|
|
|
|
|
|
|
{ |
763
|
1
|
50
|
33
|
1
|
|
25
|
if (want('OBJECT') || ! defined wantarray) |
764
|
|
|
|
|
|
|
{ |
765
|
1
|
|
|
|
|
61
|
@$op1 = @diff; |
766
|
1
|
|
|
|
|
4
|
return $op1; |
767
|
|
|
|
|
|
|
} |
768
|
1
|
|
|
|
|
11
|
}; |
769
|
|
|
|
|
|
|
|
770
|
1
|
50
|
|
|
|
16
|
if(wantarray){ return @diff } |
|
1
|
|
|
|
|
15
|
|
771
|
0
|
0
|
|
|
|
0
|
if(defined wantarray){ return \@diff } |
|
0
|
|
|
|
|
0
|
|
772
|
|
|
|
|
|
|
} |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
# Returns the elements common to both arrays |
775
|
|
|
|
|
|
|
sub intersection{ |
776
|
2
|
|
|
2
|
1
|
11
|
my($op1, $op2, $reversed) = @_; |
777
|
2
|
50
|
|
|
|
7
|
($op2,$op1) = ($op1,$op2) if $reversed; |
778
|
2
|
|
|
|
|
4
|
my($result) = []; |
779
|
|
|
|
|
|
|
|
780
|
2
|
|
|
|
|
57
|
my($i1, $i2); |
781
|
0
|
|
|
|
|
0
|
my(%seen); |
782
|
|
|
|
|
|
|
|
783
|
2
|
|
|
|
|
8
|
CORE::foreach $i1 (0 .. $#$op1){ |
784
|
10
|
|
|
|
|
27
|
CORE::foreach $i2 (0 .. $#$op2){ |
785
|
|
|
|
|
|
|
# If we have matched this value in @$op2 before, |
786
|
|
|
|
|
|
|
# do not match it in the same place again in @$op1. |
787
|
|
|
|
|
|
|
|
788
|
52
|
100
|
100
|
|
|
157
|
next if (defined $seen{$$op2[$i2]} && ($seen{$$op2[$i2]} eq $i1) ); |
789
|
|
|
|
|
|
|
|
790
|
48
|
100
|
|
|
|
110
|
if ($$op1[$i1] eq $$op2[$i2]){ |
791
|
6
|
|
|
|
|
11
|
CORE::push @$result, $$op1[$i1]; |
792
|
|
|
|
|
|
|
|
793
|
6
|
|
|
|
|
11
|
$seen{$$op2[$i2]} = $i1; |
794
|
|
|
|
|
|
|
} |
795
|
|
|
|
|
|
|
} |
796
|
|
|
|
|
|
|
} |
797
|
|
|
|
|
|
|
|
798
|
2
|
50
|
33
|
|
|
9
|
if(want('OBJECT') || !(defined wantarray)){ |
799
|
0
|
|
|
|
|
0
|
return $result; |
800
|
|
|
|
|
|
|
} |
801
|
|
|
|
|
|
|
|
802
|
2
|
50
|
|
|
|
123
|
if(wantarray){ return @$result } |
|
2
|
|
|
|
|
20
|
|
803
|
0
|
0
|
|
|
|
|
if(defined wantarray){ return $result } |
|
0
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
} |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
# Tests to see if arrays are equal (regardless of order) |
807
|
|
|
|
|
|
|
sub is_equal{ |
808
|
0
|
|
|
0
|
1
|
|
my($op1, $op2, $reversed) = @_; |
809
|
0
|
0
|
|
|
|
|
($op2,$op1) = ($op1,$op2) if $reversed; |
810
|
|
|
|
|
|
|
|
811
|
0
|
|
|
|
|
|
my(%count1, %count2); |
812
|
|
|
|
|
|
|
|
813
|
0
|
0
|
|
|
|
|
if(scalar(@$op1) != scalar(@$op2)){ return 0 } |
|
0
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
|
815
|
0
|
|
|
|
|
|
CORE::foreach(@$op1){ $count1{$_}++ } |
|
0
|
|
|
|
|
|
|
816
|
0
|
|
|
|
|
|
CORE::foreach(@$op2){ $count2{$_}++ } |
|
0
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
|
818
|
0
|
|
|
|
|
|
CORE::foreach my $key(keys %count1){ |
819
|
0
|
0
|
|
|
|
|
return 0 unless CORE::defined($count1{$key}); |
820
|
0
|
0
|
|
|
|
|
return 0 unless CORE::defined($count2{$key}); |
821
|
0
|
0
|
|
|
|
|
if($count1{$key} ne $count2{$key}){ return 0 } |
|
0
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
} |
823
|
0
|
|
|
|
|
|
return 1; |
824
|
|
|
|
|
|
|
} |
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
# Tests to see if arrays are not equal (order ignored) |
827
|
|
|
|
|
|
|
sub not_equal{ |
828
|
0
|
|
|
0
|
1
|
|
my($op1, $op2, $reversed) = @_; |
829
|
0
|
0
|
|
|
|
|
($op2,$op1) = ($op1,$op2) if $reversed; |
830
|
|
|
|
|
|
|
|
831
|
0
|
|
|
|
|
|
my(%count1, %count2); |
832
|
|
|
|
|
|
|
|
833
|
0
|
0
|
|
|
|
|
if(scalar(@$op1) != scalar(@$op2)){ return 1 } |
|
0
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
|
835
|
0
|
|
|
|
|
|
CORE::foreach(@$op1){ $count1{$_}++ } |
|
0
|
|
|
|
|
|
|
836
|
0
|
|
|
|
|
|
CORE::foreach(@$op2){ $count2{$_}++ } |
|
0
|
|
|
|
|
|
|
837
|
|
|
|
|
|
|
|
838
|
0
|
|
|
|
|
|
CORE::foreach my $key(keys %count1){ |
839
|
0
|
0
|
|
|
|
|
return 1 unless CORE::defined($count1{$key}); |
840
|
0
|
0
|
|
|
|
|
return 1 unless CORE::defined($count2{$key}); |
841
|
0
|
0
|
|
|
|
|
if($count1{$key} ne $count2{$key}){ return 1 } |
|
0
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
} |
843
|
0
|
|
|
|
|
|
return 0; |
844
|
|
|
|
|
|
|
} |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
# Returns elements in one set or the other, but not both |
847
|
|
|
|
|
|
|
sub symmetric_difference{ |
848
|
0
|
|
|
0
|
0
|
|
my($op1, $op2, $reversed) = @_; |
849
|
0
|
0
|
|
|
|
|
($op2,$op1) = ($op1,$op2) if $reversed; |
850
|
|
|
|
|
|
|
|
851
|
0
|
|
|
|
|
|
my(%count1,%count2,%count3,@symdiff); |
852
|
0
|
|
|
|
|
|
@count1{@$op1} = (1) x @$op1; |
853
|
0
|
|
|
|
|
|
@count2{@$op2} = (1) x @$op2; |
854
|
|
|
|
|
|
|
|
855
|
0
|
|
|
|
|
|
CORE::foreach(CORE::keys %count1,CORE::keys %count2){ $count3{$_}++ } |
|
0
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
|
857
|
0
|
0
|
0
|
|
|
|
if(want('OBJECT') || !(defined wantarray)){ |
858
|
0
|
|
|
|
|
|
@$op1 = CORE::grep{$count3{$_} == 1} CORE::keys %count3; |
|
0
|
|
|
|
|
|
|
859
|
0
|
|
|
|
|
|
return $op1; |
860
|
|
|
|
|
|
|
} |
861
|
|
|
|
|
|
|
|
862
|
0
|
|
|
|
|
|
@symdiff = CORE::grep{$count3{$_} == 1} CORE::keys %count3; |
|
0
|
|
|
|
|
|
|
863
|
0
|
0
|
|
|
|
|
if(wantarray){ return @symdiff } |
|
0
|
|
|
|
|
|
|
864
|
0
|
0
|
|
|
|
|
if(defined wantarray){ return \@symdiff } |
|
0
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
} |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
*sym_diff = \&symmetric_difference; |
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
# Returns the union of two arrays, non-unique values excluded |
870
|
|
|
|
|
|
|
sub union{ |
871
|
0
|
|
|
0
|
0
|
|
my($op1, $op2, $reversed) = @_; |
872
|
0
|
0
|
|
|
|
|
($op2,$op1) = ($op1,$op2) if $reversed; |
873
|
|
|
|
|
|
|
|
874
|
0
|
|
|
|
|
|
my %union; |
875
|
0
|
|
|
|
|
|
CORE::foreach(@$op1, @$op2){ $union{$_}++ } |
|
0
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
|
877
|
0
|
0
|
0
|
|
|
|
if(want('OBJECT') || !(defined wantarray)){ |
878
|
0
|
|
|
|
|
|
@$op1 = CORE::keys %union; |
879
|
0
|
|
|
|
|
|
return $op1; |
880
|
|
|
|
|
|
|
} |
881
|
|
|
|
|
|
|
|
882
|
0
|
|
|
|
|
|
my @union = CORE::keys %union; |
883
|
|
|
|
|
|
|
|
884
|
0
|
0
|
|
|
|
|
if(wantarray){ return @union } |
|
0
|
|
|
|
|
|
|
885
|
0
|
0
|
|
|
|
|
if(defined wantarray){ return \@union } |
|
0
|
|
|
|
|
|
|
886
|
|
|
|
|
|
|
} |
887
|
|
|
|
|
|
|
1; |
888
|
|
|
|
|
|
|
__END__ |