| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package List::Objects::WithUtils::Role::Array; |
|
2
|
|
|
|
|
|
|
$List::Objects::WithUtils::Role::Array::VERSION = '2.028003'; |
|
3
|
208
|
|
|
208
|
|
107687
|
use strictures 2; |
|
|
208
|
|
|
|
|
1051
|
|
|
|
208
|
|
|
|
|
7360
|
|
|
4
|
|
|
|
|
|
|
|
|
5
|
208
|
|
|
208
|
|
27731
|
use Carp (); |
|
|
208
|
|
|
|
|
242
|
|
|
|
208
|
|
|
|
|
2301
|
|
|
6
|
208
|
|
|
208
|
|
609
|
use List::Util (); |
|
|
208
|
|
|
|
|
236
|
|
|
|
208
|
|
|
|
|
2931
|
|
|
7
|
208
|
|
|
208
|
|
39578
|
use Module::Runtime (); |
|
|
208
|
|
|
|
|
115997
|
|
|
|
208
|
|
|
|
|
3858
|
|
|
8
|
208
|
|
|
208
|
|
733
|
use Scalar::Util (); |
|
|
208
|
|
|
|
|
1435
|
|
|
|
208
|
|
|
|
|
6713
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# This (and relevant tests) can disappear if UtilsBy gains XS: |
|
11
|
|
|
|
|
|
|
our $UsingUtilsByXS = 0; |
|
12
|
208
|
|
|
208
|
|
1910
|
{ no warnings 'once'; |
|
|
208
|
|
|
|
|
240
|
|
|
|
208
|
|
|
|
|
76610
|
|
|
13
|
|
|
|
|
|
|
if (eval {; require List::UtilsBy::XS; 1 } && !$@) { |
|
14
|
|
|
|
|
|
|
$UsingUtilsByXS = 1; |
|
15
|
|
|
|
|
|
|
*__sort_by = \&List::UtilsBy::XS::sort_by; |
|
16
|
|
|
|
|
|
|
*__nsort_by = \&List::UtilsBy::XS::nsort_by; |
|
17
|
|
|
|
|
|
|
*__uniq_by = \&List::UtilsBy::XS::uniq_by; |
|
18
|
|
|
|
|
|
|
} else { |
|
19
|
|
|
|
|
|
|
require List::UtilsBy; |
|
20
|
|
|
|
|
|
|
*__sort_by = \&List::UtilsBy::sort_by; |
|
21
|
|
|
|
|
|
|
*__nsort_by = \&List::UtilsBy::nsort_by; |
|
22
|
|
|
|
|
|
|
*__uniq_by = \&List::UtilsBy::uniq_by; |
|
23
|
|
|
|
|
|
|
} |
|
24
|
|
|
|
|
|
|
} |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=for Pod::Coverage ARRAY_TYPE blessed_or_pkg |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=begin comment |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
Regarding blessed_or_pkg(): |
|
32
|
|
|
|
|
|
|
This is some nonsense to support autoboxing; if we aren't blessed, we're |
|
33
|
|
|
|
|
|
|
autoboxed, in which case we appear to have no choice but to cheap out and |
|
34
|
|
|
|
|
|
|
return the basic array type. |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
This should only be called to get your hands on ->new(). |
|
37
|
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
->new() methods should be able to operate on a blessed invocant. |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=end comment |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=cut |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub ARRAY_TYPE () { 'List::Objects::WithUtils::Array' } |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub blessed_or_pkg { |
|
47
|
265
|
100
|
|
265
|
0
|
1169
|
Scalar::Util::blessed($_[0]) ? |
|
48
|
|
|
|
|
|
|
$_[0] : Module::Runtime::use_module(ARRAY_TYPE) |
|
49
|
|
|
|
|
|
|
} |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub __flatten_all { |
|
53
|
|
|
|
|
|
|
# __flatten optimized for max depth: |
|
54
|
|
|
|
|
|
|
ref $_[0] eq 'ARRAY' || Scalar::Util::blessed($_[0]) |
|
55
|
|
|
|
|
|
|
# 5.8 doesn't have ->DOES() |
|
56
|
|
|
|
|
|
|
&& $_[0]->can('does') |
|
57
|
|
|
|
|
|
|
&& $_[0]->does('List::Objects::WithUtils::Role::Array') ? |
|
58
|
45
|
100
|
66
|
45
|
|
260
|
map {; __flatten_all($_) } @{ $_[0] } |
|
|
28
|
|
|
|
|
37
|
|
|
|
10
|
|
|
|
|
2429
|
|
|
59
|
|
|
|
|
|
|
: $_[0] |
|
60
|
|
|
|
|
|
|
} |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub __flatten { |
|
63
|
29
|
|
|
29
|
|
1447
|
my $depth = shift; |
|
64
|
|
|
|
|
|
|
CORE::map { |
|
65
|
29
|
100
|
66
|
|
|
41
|
ref eq 'ARRAY' || Scalar::Util::blessed($_) |
|
|
79
|
100
|
|
|
|
393
|
|
|
66
|
|
|
|
|
|
|
&& $_->can('does') |
|
67
|
|
|
|
|
|
|
&& $_->does('List::Objects::WithUtils::Role::Array') ? |
|
68
|
|
|
|
|
|
|
$depth > 0 ? __flatten( $depth - 1, @$_ ) : $_ |
|
69
|
|
|
|
|
|
|
: $_ |
|
70
|
|
|
|
|
|
|
} @_ |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
|
|
74
|
208
|
|
|
208
|
|
873
|
use Role::Tiny; # my position relative to subs matters |
|
|
208
|
|
|
|
|
1669
|
|
|
|
208
|
|
|
|
|
2785
|
|
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
|
|
77
|
20
|
|
|
20
|
1
|
84
|
sub inflated_type { 'List::Objects::WithUtils::Hash' } |
|
78
|
|
|
|
|
|
|
|
|
79
|
2
|
|
|
2
|
1
|
7
|
sub is_mutable { 1 } |
|
80
|
2
|
|
|
2
|
1
|
19
|
sub is_immutable { ! $_[0]->is_mutable } |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub _try_coerce { |
|
83
|
|
|
|
|
|
|
# subclass-mungable (keep me under the Role::Tiny import) |
|
84
|
9
|
|
|
9
|
|
14
|
my (undef, $type, @vals) = @_; |
|
85
|
9
|
50
|
|
|
|
22
|
Carp::confess "Expected a Type::Tiny type but got $type" |
|
86
|
|
|
|
|
|
|
unless Scalar::Util::blessed $type; |
|
87
|
|
|
|
|
|
|
|
|
88
|
9
|
|
|
|
|
8
|
CORE::map {; |
|
89
|
9
|
|
|
|
|
5
|
my $coerced; |
|
90
|
9
|
50
|
|
|
|
16
|
$type->check($_) ? $_ |
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
: $type->assert_valid( |
|
92
|
|
|
|
|
|
|
$type->has_coercion ? ($coerced = $type->coerce($_)) : $_ |
|
93
|
|
|
|
|
|
|
) ? $coerced |
|
94
|
|
|
|
|
|
|
: Carp::confess "I should be unreachable!" |
|
95
|
|
|
|
|
|
|
} @vals |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=for Pod::Coverage TO_JSON TO_ZPL damn type |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=cut |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
3
|
0
|
|
sub type { |
|
104
|
|
|
|
|
|
|
# array() has an empty ->type |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
836
|
|
66
|
836
|
1
|
6809
|
sub new { bless [ @_[1 .. $#_ ] ], Scalar::Util::blessed($_[0]) || $_[0] } |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=for Pod::Coverage untyped |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=cut |
|
113
|
|
|
|
|
|
|
|
|
114
|
208
|
|
|
208
|
|
73019
|
{ no warnings 'once'; *untyped = *copy } |
|
|
208
|
|
|
|
|
276
|
|
|
|
208
|
|
|
|
|
25622
|
|
|
115
|
7
|
|
|
7
|
1
|
2803
|
sub copy { blessed_or_pkg($_[0])->new(@{ $_[0] }) } |
|
|
7
|
|
|
|
|
97
|
|
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub inflate { |
|
118
|
8
|
|
|
8
|
1
|
37
|
my ($self) = @_; |
|
119
|
8
|
|
|
|
|
20
|
my $cls = blessed_or_pkg($self); |
|
120
|
8
|
|
|
|
|
61
|
Module::Runtime::require_module( $cls->inflated_type ); |
|
121
|
8
|
|
|
|
|
130
|
$cls->inflated_type->new(@$self) |
|
122
|
|
|
|
|
|
|
} |
|
123
|
|
|
|
|
|
|
|
|
124
|
208
|
|
|
208
|
|
779
|
{ no warnings 'once'; |
|
|
208
|
|
|
|
|
241
|
|
|
|
208
|
|
|
|
|
29326
|
|
|
125
|
|
|
|
|
|
|
*TO_JSON = *unbless; |
|
126
|
|
|
|
|
|
|
*TO_ZPL = *unbless; |
|
127
|
|
|
|
|
|
|
*damn = *unbless; |
|
128
|
|
|
|
|
|
|
} |
|
129
|
10
|
|
|
10
|
1
|
1810
|
sub unbless { [ @{ $_[0] } ] } |
|
|
10
|
|
|
|
|
36
|
|
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub validated { |
|
132
|
3
|
|
|
3
|
1
|
2659
|
my ($self, $type) = @_; |
|
133
|
|
|
|
|
|
|
# Autoboxed? |
|
134
|
3
|
100
|
|
|
|
11
|
$self = blessed_or_pkg($self)->new(@$self) |
|
135
|
|
|
|
|
|
|
unless Scalar::Util::blessed $self; |
|
136
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
137
|
3
|
|
|
|
|
6
|
CORE::map {; $self->_try_coerce($type, $_) } @$self |
|
|
9
|
|
|
|
|
73
|
|
|
138
|
|
|
|
|
|
|
) |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
|
|
141
|
246
|
|
|
246
|
1
|
9979
|
sub all { @{ $_[0] } } |
|
|
246
|
|
|
|
|
1408
|
|
|
142
|
208
|
|
|
208
|
|
877
|
{ no warnings 'once'; *export = *all; *elements = *all; } |
|
|
208
|
|
|
|
|
253
|
|
|
|
208
|
|
|
|
|
12752
|
|
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=for Pod::Coverage size |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=cut |
|
148
|
|
|
|
|
|
|
|
|
149
|
57
|
|
|
57
|
1
|
9324
|
sub count { CORE::scalar @{ $_[0] } } |
|
|
57
|
|
|
|
|
251
|
|
|
150
|
208
|
|
|
208
|
|
723
|
{ no warnings 'once'; *scalar = *count; *size = *count; } |
|
|
208
|
|
|
|
|
237
|
|
|
|
208
|
|
|
|
|
200019
|
|
|
151
|
|
|
|
|
|
|
|
|
152
|
4
|
|
|
4
|
1
|
19
|
sub end { $#{ $_[0] } } |
|
|
4
|
|
|
|
|
21
|
|
|
153
|
|
|
|
|
|
|
|
|
154
|
68
|
|
|
68
|
1
|
1385
|
sub is_empty { ! @{ $_[0] } } |
|
|
68
|
|
|
|
|
280
|
|
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub exists { |
|
157
|
21
|
|
|
21
|
1
|
45
|
my $r; |
|
158
|
|
|
|
|
|
|
!!( |
|
159
|
21
|
|
|
|
|
145
|
$_[1] <= $#{ $_[0] } ? $_[1] >= 0 ? 1 |
|
160
|
21
|
100
|
66
|
|
|
21
|
: (($r = $_[1] + @{ $_[0] }) <= $#{ $_[0] } && $r >= 0) ? 1 : () |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
: () |
|
162
|
|
|
|
|
|
|
) |
|
163
|
|
|
|
|
|
|
} |
|
164
|
|
|
|
|
|
|
|
|
165
|
6
|
|
|
6
|
1
|
42
|
sub defined { defined $_[0]->[ $_[1] ] } |
|
166
|
|
|
|
|
|
|
|
|
167
|
44
|
|
|
44
|
1
|
554
|
sub get { $_[0]->[ $_[1] ] } |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub get_or_else { |
|
170
|
8
|
100
|
100
|
8
|
1
|
118
|
defined $_[0]->[ $_[1] ] ? $_[0]->[ $_[1] ] |
|
|
|
100
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
: (Scalar::Util::reftype $_[2] || '') eq 'CODE' ? $_[2]->(@_[0,1]) |
|
172
|
|
|
|
|
|
|
: $_[2] |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
|
|
175
|
7
|
|
|
7
|
1
|
710
|
sub set { $_[0]->[ $_[1] ] = $_[2] ; $_[0] } |
|
|
6
|
|
|
|
|
30
|
|
|
176
|
|
|
|
|
|
|
|
|
177
|
4
|
|
|
4
|
1
|
22
|
sub random { $_[0]->[ rand @{ $_[0] } ] } |
|
|
4
|
|
|
|
|
96
|
|
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub kv { |
|
180
|
3
|
|
|
3
|
1
|
21
|
my ($self) = @_; |
|
181
|
|
|
|
|
|
|
blessed_or_pkg($self)->new( |
|
182
|
3
|
|
|
|
|
7
|
map {; [ $_ => $self->[$_] ] } 0 .. $#$self |
|
|
8
|
|
|
|
|
46
|
|
|
183
|
|
|
|
|
|
|
) |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub head { |
|
187
|
|
|
|
|
|
|
wantarray ? |
|
188
|
|
|
|
|
|
|
( |
|
189
|
|
|
|
|
|
|
$_[0]->[0], |
|
190
|
6
|
100
|
|
6
|
1
|
1239
|
blessed_or_pkg($_[0])->new( @{ $_[0] }[ 1 .. $#{$_[0]} ] ) |
|
|
3
|
|
|
|
|
12
|
|
|
|
3
|
|
|
|
|
35
|
|
|
191
|
|
|
|
|
|
|
) |
|
192
|
|
|
|
|
|
|
: $_[0]->[0] |
|
193
|
|
|
|
|
|
|
} |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
sub tail { |
|
196
|
|
|
|
|
|
|
wantarray ? |
|
197
|
|
|
|
|
|
|
( |
|
198
|
|
|
|
|
|
|
$_[0]->[-1], |
|
199
|
6
|
100
|
|
6
|
1
|
1162
|
blessed_or_pkg($_[0])->new( @{ $_[0] }[ 0 .. ($#{$_[0]} - 1) ] ) |
|
|
3
|
|
|
|
|
8
|
|
|
|
3
|
|
|
|
|
36
|
|
|
200
|
|
|
|
|
|
|
) |
|
201
|
|
|
|
|
|
|
: $_[0]->[-1] |
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
|
|
204
|
4
|
|
|
4
|
1
|
14
|
sub pop { CORE::pop @{ $_[0] } } |
|
|
4
|
|
|
|
|
20
|
|
|
205
|
|
|
|
|
|
|
sub push { |
|
206
|
14
|
|
|
14
|
1
|
876
|
CORE::push @{ $_[0] }, @_[1 .. $#_]; |
|
|
14
|
|
|
|
|
72
|
|
|
207
|
13
|
|
|
|
|
45
|
$_[0] |
|
208
|
|
|
|
|
|
|
} |
|
209
|
|
|
|
|
|
|
|
|
210
|
4
|
|
|
4
|
1
|
21
|
sub shift { CORE::shift @{ $_[0] } } |
|
|
4
|
|
|
|
|
18
|
|
|
211
|
|
|
|
|
|
|
sub unshift { |
|
212
|
6
|
|
|
6
|
1
|
680
|
CORE::unshift @{ $_[0] }, @_[1 .. $#_]; |
|
|
6
|
|
|
|
|
25
|
|
|
213
|
5
|
|
|
|
|
37
|
$_[0] |
|
214
|
|
|
|
|
|
|
} |
|
215
|
|
|
|
|
|
|
|
|
216
|
4
|
|
|
4
|
1
|
31
|
sub clear { @{ $_[0] } = (); $_[0] } |
|
|
4
|
|
|
|
|
13
|
|
|
|
4
|
|
|
|
|
14
|
|
|
217
|
|
|
|
|
|
|
|
|
218
|
4
|
|
|
4
|
1
|
31
|
sub delete { scalar CORE::splice @{ $_[0] }, $_[1], 1 } |
|
|
4
|
|
|
|
|
28
|
|
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
sub delete_when { |
|
221
|
8
|
|
|
8
|
1
|
39
|
my ($self, $cb) = @_; |
|
222
|
8
|
|
|
|
|
8
|
my @removed; |
|
223
|
8
|
|
|
|
|
12
|
my $i = @$self; |
|
224
|
8
|
|
|
|
|
22
|
while ($i--) { |
|
225
|
24
|
|
|
|
|
85
|
local *_ = \$self->[$i]; |
|
226
|
24
|
100
|
|
|
|
34
|
CORE::push @removed, CORE::splice @$self, $i, 1 if $cb->($_); |
|
227
|
|
|
|
|
|
|
} |
|
228
|
8
|
|
|
|
|
36
|
blessed_or_pkg($_[0])->new(@removed) |
|
229
|
|
|
|
|
|
|
} |
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub insert { |
|
232
|
13
|
100
|
|
13
|
1
|
439
|
$#{$_[0]} = ($_[1]-1) if $_[1] > $#{$_[0]}; |
|
|
6
|
|
|
|
|
19
|
|
|
|
13
|
|
|
|
|
67
|
|
|
233
|
13
|
|
|
|
|
27
|
CORE::splice @{ $_[0] }, $_[1], 0, @_[2 .. $#_]; |
|
|
13
|
|
|
|
|
62
|
|
|
234
|
12
|
|
|
|
|
50
|
$_[0] |
|
235
|
|
|
|
|
|
|
} |
|
236
|
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub intersection { |
|
238
|
6
|
|
|
6
|
1
|
27
|
my %seen; |
|
239
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
240
|
|
|
|
|
|
|
# Well. Probably not the most efficient approach . . . |
|
241
|
57
|
|
|
|
|
65
|
CORE::grep {; ++$seen{$_} > $#_ } |
|
242
|
6
|
|
|
|
|
15
|
CORE::map {; |
|
243
|
14
|
|
|
|
|
44
|
my %s = (); CORE::grep {; not $s{$_}++ } @$_ |
|
|
14
|
|
|
|
|
21
|
|
|
|
58
|
|
|
|
|
92
|
|
|
244
|
|
|
|
|
|
|
} @_ |
|
245
|
|
|
|
|
|
|
) |
|
246
|
|
|
|
|
|
|
} |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
sub diff { |
|
249
|
10
|
|
|
10
|
1
|
33
|
my %seen; |
|
250
|
10
|
|
|
|
|
15
|
my @vals = CORE::map {; |
|
251
|
21
|
|
|
|
|
25
|
my %s = (); CORE::grep {; not $s{$_}++ } @$_ |
|
|
21
|
|
|
|
|
29
|
|
|
|
60
|
|
|
|
|
130
|
|
|
252
|
|
|
|
|
|
|
} @_; |
|
253
|
10
|
|
|
|
|
40
|
$seen{$_}++ for @vals; |
|
254
|
10
|
|
|
|
|
12
|
my %inner; |
|
255
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
256
|
40
|
|
|
|
|
56
|
CORE::grep {; $seen{$_} != @_ } |
|
257
|
10
|
|
|
|
|
27
|
CORE::grep {; not $inner{$_}++ } @vals |
|
|
60
|
|
|
|
|
141
|
|
|
258
|
|
|
|
|
|
|
) |
|
259
|
|
|
|
|
|
|
} |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
sub join { |
|
262
|
|
|
|
|
|
|
CORE::join( |
|
263
|
|
|
|
|
|
|
( defined $_[1] ? $_[1] : ',' ), |
|
264
|
8
|
100
|
|
8
|
1
|
27
|
@{ $_[0] } |
|
|
8
|
|
|
|
|
41
|
|
|
265
|
|
|
|
|
|
|
) |
|
266
|
|
|
|
|
|
|
} |
|
267
|
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
sub map { |
|
269
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
270
|
13
|
|
|
13
|
1
|
888
|
CORE::map {; $_[1]->($_) } @{ $_[0] } |
|
|
51
|
|
|
|
|
162
|
|
|
|
13
|
|
|
|
|
162
|
|
|
271
|
|
|
|
|
|
|
) |
|
272
|
|
|
|
|
|
|
} |
|
273
|
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
sub mapval { |
|
275
|
6
|
|
|
6
|
1
|
27
|
my ($self, $cb) = @_; |
|
276
|
6
|
|
|
|
|
10
|
my @copy = @$self; |
|
277
|
|
|
|
|
|
|
blessed_or_pkg($self)->new( |
|
278
|
6
|
|
|
|
|
14
|
CORE::map {; $cb->($_); $_ } @copy |
|
|
12
|
|
|
|
|
62
|
|
|
|
12
|
|
|
|
|
28
|
|
|
279
|
|
|
|
|
|
|
) |
|
280
|
|
|
|
|
|
|
} |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
sub visit { |
|
283
|
4
|
|
|
4
|
1
|
832
|
$_[1]->($_) for @{ $_[0] }; |
|
|
4
|
|
|
|
|
16
|
|
|
284
|
4
|
|
|
|
|
16
|
$_[0] |
|
285
|
|
|
|
|
|
|
} |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub grep { |
|
288
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
289
|
7
|
|
|
7
|
1
|
42
|
CORE::grep {; $_[1]->($_) } @{ $_[0] } |
|
|
19
|
|
|
|
|
48
|
|
|
|
7
|
|
|
|
|
81
|
|
|
290
|
|
|
|
|
|
|
) |
|
291
|
|
|
|
|
|
|
} |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=for Pod::Coverage indices |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=cut |
|
298
|
|
|
|
|
|
|
|
|
299
|
208
|
|
|
208
|
|
939
|
{ no warnings 'once'; *indices = *indexes; } |
|
|
208
|
|
|
|
|
268
|
|
|
|
208
|
|
|
|
|
26019
|
|
|
300
|
|
|
|
|
|
|
sub indexes { |
|
301
|
|
|
|
|
|
|
$_[1] ? |
|
302
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
303
|
32
|
|
|
|
|
75
|
grep {; local *_ = \$_[0]->[$_]; $_[1]->() } 0 .. $#{ $_[0] } |
|
|
32
|
|
|
|
|
38
|
|
|
|
8
|
|
|
|
|
101
|
|
|
304
|
|
|
|
|
|
|
) |
|
305
|
10
|
100
|
|
10
|
1
|
51
|
: blessed_or_pkg($_[0])->new( 0 .. $#{ $_[0] } ) |
|
|
2
|
|
|
|
|
26
|
|
|
306
|
|
|
|
|
|
|
} |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub sort { |
|
309
|
37
|
100
|
66
|
37
|
1
|
1201
|
if (defined $_[1] && (my $cb = $_[1])) { |
|
310
|
12
|
|
|
|
|
30
|
my $pkg = caller; |
|
311
|
208
|
|
|
208
|
|
892
|
no strict 'refs'; |
|
|
208
|
|
|
|
|
309
|
|
|
|
208
|
|
|
|
|
32334
|
|
|
312
|
|
|
|
|
|
|
return blessed_or_pkg($_[0])->new( |
|
313
|
|
|
|
|
|
|
CORE::sort {; |
|
314
|
43
|
|
|
|
|
114
|
local (*{"${pkg}::a"}, *{"${pkg}::b"}) = (\$a, \$b); |
|
|
43
|
|
|
|
|
61
|
|
|
|
43
|
|
|
|
|
64
|
|
|
315
|
43
|
|
|
|
|
62
|
$a->$cb($b) |
|
316
|
12
|
|
|
|
|
31
|
} @{ $_[0] } |
|
|
12
|
|
|
|
|
84
|
|
|
317
|
|
|
|
|
|
|
) |
|
318
|
|
|
|
|
|
|
} |
|
319
|
25
|
|
|
|
|
54
|
blessed_or_pkg($_[0])->new( CORE::sort @{ $_[0] } ) |
|
|
25
|
|
|
|
|
137
|
|
|
320
|
|
|
|
|
|
|
} |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
sub reverse { |
|
323
|
4
|
|
|
4
|
1
|
27
|
blessed_or_pkg($_[0])->new( CORE::reverse @{ $_[0] } ) |
|
|
4
|
|
|
|
|
60
|
|
|
324
|
|
|
|
|
|
|
} |
|
325
|
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
=for Pod::Coverage slice |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=cut |
|
330
|
|
|
|
|
|
|
|
|
331
|
208
|
|
|
208
|
|
822
|
{ no warnings 'once'; *slice = *sliced } |
|
|
208
|
|
|
|
|
220
|
|
|
|
208
|
|
|
|
|
33881
|
|
|
332
|
|
|
|
|
|
|
sub sliced { |
|
333
|
6
|
|
|
6
|
1
|
30
|
my @safe = @{ $_[0] }; |
|
|
6
|
|
|
|
|
15
|
|
|
334
|
6
|
|
|
|
|
14
|
blessed_or_pkg($_[0])->new( @safe[ @_[1 .. $#_] ] ) |
|
335
|
|
|
|
|
|
|
} |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
sub splice { |
|
338
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
339
|
2
|
|
|
|
|
62
|
@_ == 2 ? CORE::splice( @{ $_[0] }, $_[1] ) |
|
340
|
8
|
100
|
|
8
|
1
|
452
|
: CORE::splice( @{ $_[0] }, $_[1], $_[2], @_[3 .. $#_] ) |
|
|
6
|
|
|
|
|
45
|
|
|
341
|
|
|
|
|
|
|
) |
|
342
|
|
|
|
|
|
|
} |
|
343
|
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
sub has_any { |
|
345
|
15
|
|
|
|
|
88
|
defined $_[1] ? !! &List::Util::any( $_[1], @{ $_[0] } ) |
|
346
|
27
|
100
|
|
27
|
1
|
754
|
: !! @{ $_[0] } |
|
|
12
|
|
|
|
|
53
|
|
|
347
|
|
|
|
|
|
|
} |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=for Pod::Coverage first |
|
351
|
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=cut |
|
353
|
|
|
|
|
|
|
|
|
354
|
208
|
|
|
208
|
|
803
|
{ no warnings 'once'; *first = *first_where } |
|
|
208
|
|
|
|
|
238
|
|
|
|
208
|
|
|
|
|
27544
|
|
|
355
|
5
|
|
|
5
|
1
|
1196
|
sub first_where { &List::Util::first( $_[1], @{ $_[0] } ) } |
|
|
5
|
|
|
|
|
58
|
|
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub last_where { |
|
358
|
8
|
|
|
8
|
1
|
42
|
my ($self, $cb) = @_; |
|
359
|
8
|
|
|
|
|
12
|
my $i = @$self; |
|
360
|
8
|
|
|
|
|
22
|
while ($i--) { |
|
361
|
19
|
|
|
|
|
21
|
local *_ = \$self->[$i]; |
|
362
|
19
|
|
|
|
|
28
|
my $ret = $cb->(); |
|
363
|
19
|
|
|
|
|
60
|
$self->[$i] = $_; |
|
364
|
19
|
100
|
|
|
|
56
|
return $_ if $ret; |
|
365
|
|
|
|
|
|
|
} |
|
366
|
|
|
|
|
|
|
undef |
|
367
|
4
|
|
|
|
|
19
|
} |
|
368
|
|
|
|
|
|
|
|
|
369
|
208
|
|
|
208
|
|
807
|
{ no warnings 'once'; |
|
|
208
|
|
|
|
|
233
|
|
|
|
208
|
|
|
|
|
30649
|
|
|
370
|
|
|
|
|
|
|
*first_index = *firstidx; |
|
371
|
|
|
|
|
|
|
*last_index = *lastidx; |
|
372
|
|
|
|
|
|
|
} |
|
373
|
|
|
|
|
|
|
sub firstidx { |
|
374
|
9
|
|
|
9
|
1
|
1221
|
my ($self, $cb) = @_; |
|
375
|
9
|
|
|
|
|
30
|
for my $i (0 .. $#$self) { |
|
376
|
20
|
|
|
|
|
73
|
local *_ = \$self->[$i]; |
|
377
|
20
|
100
|
|
|
|
28
|
return $i if $cb->(); |
|
378
|
|
|
|
|
|
|
} |
|
379
|
4
|
|
|
|
|
17
|
-1 |
|
380
|
|
|
|
|
|
|
} |
|
381
|
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
sub lastidx { |
|
383
|
7
|
|
|
7
|
1
|
30
|
my ($self, $cb) = @_; |
|
384
|
7
|
|
|
|
|
19
|
for my $i (CORE::reverse 0 .. $#$self) { |
|
385
|
14
|
|
|
|
|
42
|
local *_ = \$self->[$i]; |
|
386
|
14
|
100
|
|
|
|
18
|
return $i if $cb->(); |
|
387
|
|
|
|
|
|
|
} |
|
388
|
4
|
|
|
|
|
24
|
-1 |
|
389
|
|
|
|
|
|
|
} |
|
390
|
|
|
|
|
|
|
|
|
391
|
208
|
|
|
208
|
|
1800
|
{ no warnings 'once'; *zip = *mesh; } |
|
|
208
|
|
|
|
|
265
|
|
|
|
208
|
|
|
|
|
158056
|
|
|
392
|
|
|
|
|
|
|
sub mesh { |
|
393
|
8
|
|
|
8
|
1
|
8
|
my $max_idx = -1; |
|
394
|
8
|
100
|
|
|
|
17
|
for (@_) { $max_idx = $#$_ if $max_idx < $#$_ } |
|
|
19
|
|
|
|
|
51
|
|
|
395
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
396
|
7
|
|
|
|
|
16
|
CORE::map {; |
|
397
|
25
|
|
|
|
|
44
|
my $idx = $_; map {; $_->[$idx] } @_ |
|
|
25
|
|
|
|
|
20
|
|
|
|
53
|
|
|
|
|
56
|
|
|
398
|
|
|
|
|
|
|
} 0 .. $max_idx |
|
399
|
|
|
|
|
|
|
) |
|
400
|
|
|
|
|
|
|
} |
|
401
|
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
sub natatime { |
|
403
|
6
|
|
|
6
|
1
|
23
|
my @list = @{ $_[0] }; |
|
|
6
|
|
|
|
|
15
|
|
|
404
|
6
|
|
|
|
|
7
|
my $count = $_[1]; |
|
405
|
6
|
|
|
15
|
|
19
|
my $itr = sub { CORE::splice @list, 0, $count }; |
|
|
15
|
|
|
|
|
78
|
|
|
406
|
6
|
100
|
|
|
|
16
|
if (defined $_[2]) { |
|
407
|
2
|
|
|
|
|
6
|
while (my @nxt = $itr->()) { $_[2]->(@nxt) } |
|
|
6
|
|
|
|
|
10
|
|
|
408
|
|
|
|
|
|
|
return |
|
409
|
2
|
|
|
|
|
6
|
} |
|
410
|
|
|
|
|
|
|
$itr |
|
411
|
4
|
|
|
|
|
6
|
} |
|
412
|
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
sub rotator { |
|
414
|
4
|
|
|
4
|
1
|
23
|
my @list = @{ $_[0] }; |
|
|
4
|
|
|
|
|
12
|
|
|
415
|
4
|
|
|
|
|
7
|
my $pos = 0; |
|
416
|
|
|
|
|
|
|
sub { |
|
417
|
16
|
|
|
16
|
|
45
|
my $val = $list[$pos++]; |
|
418
|
16
|
100
|
|
|
|
27
|
$pos = 0 if $pos == @list; |
|
419
|
16
|
|
|
|
|
29
|
$val |
|
420
|
|
|
|
|
|
|
} |
|
421
|
4
|
|
|
|
|
19
|
} |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
sub part { |
|
424
|
4
|
|
|
4
|
1
|
19
|
my ($self, $code) = @_; |
|
425
|
4
|
|
|
|
|
6
|
my @parts; |
|
426
|
4
|
|
|
|
|
12
|
CORE::push @{ $parts[ $code->($_) ] }, $_ for @$self; |
|
|
36
|
|
|
|
|
110
|
|
|
427
|
4
|
|
|
|
|
18
|
my $cls = blessed_or_pkg($self); |
|
428
|
|
|
|
|
|
|
$cls->new( |
|
429
|
4
|
100
|
|
|
|
33
|
map {; $cls->new(defined $_ ? @$_ : () ) } @parts |
|
|
11
|
|
|
|
|
31
|
|
|
430
|
|
|
|
|
|
|
) |
|
431
|
|
|
|
|
|
|
} |
|
432
|
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
sub part_to_hash { |
|
434
|
2
|
|
|
2
|
1
|
26
|
my ($self, $code) = @_; |
|
435
|
2
|
|
|
|
|
4
|
my %parts; |
|
436
|
2
|
|
|
|
|
8
|
CORE::push @{ $parts{ $code->($_) } }, $_ for @$self; |
|
|
10
|
|
|
|
|
38
|
|
|
437
|
2
|
|
|
|
|
10
|
my $cls = blessed_or_pkg($self); |
|
438
|
2
|
|
|
|
|
42
|
Module::Runtime::require_module( $cls->inflated_type ); |
|
439
|
2
|
|
|
|
|
18
|
@parts{keys %parts} = map {; $cls->new(@$_) } values %parts; |
|
|
6
|
|
|
|
|
13
|
|
|
440
|
2
|
|
|
|
|
7
|
$cls->inflated_type->new(%parts) |
|
441
|
|
|
|
|
|
|
} |
|
442
|
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
sub bisect { |
|
444
|
4
|
|
|
4
|
1
|
27
|
my ($self, $code) = @_; |
|
445
|
4
|
|
|
|
|
9
|
my @parts = ( [], [] ); |
|
446
|
4
|
100
|
|
|
|
11
|
CORE::push @{ $parts[ $code->($_) ? 0 : 1 ] }, $_ for @$self; |
|
|
20
|
|
|
|
|
64
|
|
|
447
|
4
|
|
|
|
|
13
|
my $cls = blessed_or_pkg($self); |
|
448
|
4
|
|
|
|
|
48
|
$cls->new( map {; $cls->new(@$_) } @parts ) |
|
|
8
|
|
|
|
|
15
|
|
|
449
|
|
|
|
|
|
|
} |
|
450
|
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
sub nsect { |
|
452
|
6
|
|
|
6
|
1
|
26
|
my ($self, $sections) = @_; |
|
453
|
6
|
|
|
|
|
12
|
my $total = scalar @$self; |
|
454
|
6
|
|
|
|
|
6
|
my @parts; |
|
455
|
6
|
|
|
|
|
5
|
my $x = 0; |
|
456
|
6
|
100
|
|
|
|
19
|
$sections = $total if (defined $sections ? $sections : 0) > $total; |
|
|
|
100
|
|
|
|
|
|
|
457
|
6
|
100
|
66
|
|
|
28
|
if ($sections && $total) { |
|
458
|
4
|
|
|
|
|
8
|
CORE::push @{ $parts[ int($x++ * $sections / $total) ] }, $_ for @$self; |
|
|
33
|
|
|
|
|
53
|
|
|
459
|
|
|
|
|
|
|
} |
|
460
|
6
|
|
|
|
|
12
|
my $cls = blessed_or_pkg($self); |
|
461
|
6
|
|
|
|
|
43
|
$cls->new( map {; $cls->new(@$_) } @parts ) |
|
|
10
|
|
|
|
|
18
|
|
|
462
|
|
|
|
|
|
|
} |
|
463
|
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
sub ssect { |
|
465
|
5
|
|
|
5
|
1
|
24
|
my ($self, $per) = @_; |
|
466
|
5
|
|
|
|
|
5
|
my @parts; |
|
467
|
5
|
|
|
|
|
6
|
my $x = 0; |
|
468
|
5
|
100
|
|
|
|
10
|
if ($per) { |
|
469
|
4
|
|
|
|
|
12
|
CORE::push @{ $parts[ int($x++ / $per) ] }, $_ for @$self; |
|
|
20
|
|
|
|
|
29
|
|
|
470
|
|
|
|
|
|
|
} |
|
471
|
5
|
|
|
|
|
11
|
my $cls = blessed_or_pkg($self); |
|
472
|
5
|
|
|
|
|
58
|
$cls->new( map {; $cls->new(@$_) } @parts ) |
|
|
8
|
|
|
|
|
14
|
|
|
473
|
|
|
|
|
|
|
} |
|
474
|
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
sub tuples { |
|
476
|
8
|
|
|
8
|
1
|
31
|
my ($self, $size, $type, $bless) = @_; |
|
477
|
8
|
100
|
|
|
|
16
|
$size = 2 unless defined $size; |
|
478
|
8
|
100
|
|
|
|
174
|
Carp::confess "Expected a positive integer size but got $size" |
|
479
|
|
|
|
|
|
|
if $size < 1; |
|
480
|
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
# Autoboxed? Need to be blessed if we're to _try_coerce: |
|
482
|
7
|
|
|
|
|
12
|
my $cls = blessed_or_pkg($self); |
|
483
|
7
|
50
|
33
|
|
|
46
|
$self = $cls->new(@$self) |
|
484
|
|
|
|
|
|
|
if defined $type and not Scalar::Util::blessed $self; |
|
485
|
|
|
|
|
|
|
|
|
486
|
7
|
|
|
|
|
7
|
my $itr = do { |
|
487
|
7
|
|
|
|
|
15
|
my @copy = @$self; |
|
488
|
25
|
|
|
25
|
|
46
|
sub { CORE::splice @copy, 0, $size } |
|
489
|
7
|
|
|
|
|
23
|
}; |
|
490
|
7
|
|
|
|
|
8
|
my @res; |
|
491
|
7
|
|
|
|
|
10
|
while (my @nxt = $itr->()) { |
|
492
|
18
|
50
|
|
|
|
22
|
@nxt = CORE::map {; $self->_try_coerce($type, $_) } @nxt |
|
|
0
|
|
|
|
|
0
|
|
|
493
|
|
|
|
|
|
|
if defined $type; |
|
494
|
18
|
100
|
|
|
|
41
|
CORE::push @res, $bless ? $cls->new(@nxt) : [ @nxt ]; |
|
495
|
|
|
|
|
|
|
} |
|
496
|
|
|
|
|
|
|
|
|
497
|
7
|
|
|
|
|
13
|
$cls->new(@res) |
|
498
|
|
|
|
|
|
|
} |
|
499
|
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=for Pod::Coverage fold_left foldl fold_right |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=cut |
|
504
|
|
|
|
|
|
|
|
|
505
|
208
|
|
|
208
|
|
1179
|
{ no warnings 'once'; *foldl = *reduce; *fold_left = *reduce; } |
|
|
208
|
|
|
|
|
245
|
|
|
|
208
|
|
|
|
|
10415
|
|
|
506
|
|
|
|
|
|
|
sub reduce { |
|
507
|
10
|
|
|
10
|
1
|
658
|
my $pkg = caller; |
|
508
|
208
|
|
|
208
|
|
796
|
no strict 'refs'; |
|
|
208
|
|
|
|
|
849
|
|
|
|
208
|
|
|
|
|
20334
|
|
|
509
|
10
|
|
|
|
|
11
|
my $cb = $_[1]; |
|
510
|
|
|
|
|
|
|
List::Util::reduce { |
|
511
|
12
|
|
|
12
|
|
28
|
local (*{"${pkg}::a"}, *{"${pkg}::b"}) = (\$a, \$b); |
|
|
12
|
|
|
|
|
24
|
|
|
|
12
|
|
|
|
|
21
|
|
|
512
|
12
|
|
|
|
|
22
|
$a->$cb($b) |
|
513
|
10
|
|
|
|
|
29
|
} @{ $_[0] } |
|
|
10
|
|
|
|
|
68
|
|
|
514
|
|
|
|
|
|
|
} |
|
515
|
|
|
|
|
|
|
|
|
516
|
208
|
|
|
208
|
|
764
|
{ no warnings 'once'; *fold_right = *foldr; } |
|
|
208
|
|
|
|
|
243
|
|
|
|
208
|
|
|
|
|
9701
|
|
|
517
|
|
|
|
|
|
|
sub foldr { |
|
518
|
5
|
|
|
5
|
1
|
403
|
my $pkg = caller; |
|
519
|
208
|
|
|
208
|
|
689
|
no strict 'refs'; |
|
|
208
|
|
|
|
|
224
|
|
|
|
208
|
|
|
|
|
113798
|
|
|
520
|
5
|
|
|
|
|
8
|
my $cb = $_[1]; |
|
521
|
|
|
|
|
|
|
List::Util::reduce { |
|
522
|
6
|
|
|
6
|
|
18
|
local (*{"${pkg}::a"}, *{"${pkg}::b"}) = (\$b, \$a); |
|
|
6
|
|
|
|
|
16
|
|
|
|
6
|
|
|
|
|
13
|
|
|
523
|
6
|
|
|
|
|
16
|
$a->$cb($b) |
|
524
|
5
|
|
|
|
|
17
|
} CORE::reverse @{ $_[0] } |
|
|
5
|
|
|
|
|
27
|
|
|
525
|
|
|
|
|
|
|
} |
|
526
|
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
sub rotate { |
|
528
|
18
|
|
|
18
|
1
|
48
|
my ($self, %params) = @_; |
|
529
|
|
|
|
|
|
|
$params{left} && $params{right} ? |
|
530
|
|
|
|
|
|
|
Carp::confess "Cannot rotate in both directions!" |
|
531
|
|
|
|
|
|
|
: $params{right} ? |
|
532
|
|
|
|
|
|
|
blessed_or_pkg($self)->new( |
|
533
|
3
|
|
|
|
|
6
|
@$self ? ($self->[-1], @{ $self }[0 .. ($#$self - 1)]) : () |
|
534
|
|
|
|
|
|
|
) |
|
535
|
|
|
|
|
|
|
: blessed_or_pkg($self)->new( |
|
536
|
18
|
100
|
66
|
|
|
356
|
@$self ? (@{ $self }[1 .. $#$self], $self->[0]) : () |
|
|
10
|
100
|
|
|
|
126
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
) |
|
538
|
|
|
|
|
|
|
} |
|
539
|
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
sub rotate_in_place { |
|
541
|
7
|
100
|
|
7
|
1
|
507
|
$_[0] = Scalar::Util::blessed $_[0] ? |
|
542
|
|
|
|
|
|
|
$_[0]->rotate(@_[1 .. $#_]) : rotate(@_) |
|
543
|
|
|
|
|
|
|
} |
|
544
|
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
sub items_after { |
|
546
|
6
|
|
|
6
|
1
|
26
|
my ($started, $lag); |
|
547
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
548
|
|
|
|
|
|
|
CORE::grep $started ||= do { |
|
549
|
22
|
|
|
|
|
20
|
my $x = $lag; $lag = $_[1]->(); $x |
|
|
22
|
|
|
|
|
32
|
|
|
|
22
|
|
|
|
|
91
|
|
|
550
|
6
|
|
100
|
|
|
14
|
}, @{ $_[0] } |
|
|
6
|
|
|
|
|
89
|
|
|
551
|
|
|
|
|
|
|
) |
|
552
|
|
|
|
|
|
|
} |
|
553
|
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
sub items_after_incl { |
|
555
|
6
|
|
|
6
|
1
|
26
|
my $started; |
|
556
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
557
|
6
|
|
100
|
|
|
14
|
CORE::grep $started ||= $_[1]->(), @{ $_[0] } |
|
|
6
|
|
|
|
|
92
|
|
|
558
|
|
|
|
|
|
|
) |
|
559
|
|
|
|
|
|
|
} |
|
560
|
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
sub items_before { |
|
562
|
6
|
|
|
6
|
1
|
29
|
my $more = 1; |
|
563
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
564
|
6
|
|
100
|
|
|
12
|
CORE::grep $more &&= !$_[1]->(), @{ $_[0] } |
|
|
6
|
|
|
|
|
105
|
|
|
565
|
|
|
|
|
|
|
) |
|
566
|
|
|
|
|
|
|
} |
|
567
|
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
sub items_before_incl { |
|
569
|
4
|
|
|
4
|
1
|
32
|
my $more = 1; my $lag = 1; |
|
|
4
|
|
|
|
|
5
|
|
|
570
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
571
|
10
|
|
|
|
|
9
|
CORE::grep $more &&= do { my $x = $lag; $lag = !$_[1]->(); $x }, |
|
|
10
|
|
|
|
|
16
|
|
|
|
10
|
|
|
|
|
40
|
|
|
572
|
4
|
|
100
|
|
|
7
|
@{ $_[0] } |
|
|
4
|
|
|
|
|
62
|
|
|
573
|
|
|
|
|
|
|
) |
|
574
|
|
|
|
|
|
|
} |
|
575
|
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
sub pick { |
|
577
|
4
|
100
|
|
4
|
1
|
1719
|
return $_[0]->shuffle if $_[1] >= @{ $_[0] }; |
|
|
4
|
|
|
|
|
19
|
|
|
578
|
1
|
|
|
|
|
1
|
my %idx; |
|
579
|
1
|
|
|
|
|
3
|
$idx{ int rand @{ $_[0] } } = 1 until keys %idx == $_[1]; |
|
|
4
|
|
|
|
|
34
|
|
|
580
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
581
|
1
|
|
|
|
|
3
|
@{ $_[0] }[keys %idx] |
|
|
1
|
|
|
|
|
3
|
|
|
582
|
|
|
|
|
|
|
) |
|
583
|
|
|
|
|
|
|
} |
|
584
|
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
sub roll { |
|
586
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
587
|
3
|
|
|
|
|
8
|
@{ $_[0] }[ |
|
588
|
14
|
|
|
|
|
16
|
map {; int rand @{ $_[0] } } |
|
|
14
|
|
|
|
|
45
|
|
|
589
|
3
|
50
|
|
3
|
1
|
825
|
0 .. (defined $_[1] ? $_[1] : @{ $_[0] }) - 1 |
|
|
0
|
|
|
|
|
0
|
|
|
590
|
|
|
|
|
|
|
] |
|
591
|
|
|
|
|
|
|
) |
|
592
|
|
|
|
|
|
|
} |
|
593
|
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
sub shuffle { |
|
595
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
596
|
6
|
|
|
6
|
1
|
31
|
List::Util::shuffle( @{ $_[0] } ) |
|
|
6
|
|
|
|
|
101
|
|
|
597
|
|
|
|
|
|
|
) |
|
598
|
|
|
|
|
|
|
} |
|
599
|
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
=for Pod::Coverage squish |
|
601
|
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
=cut |
|
603
|
|
|
|
|
|
|
|
|
604
|
208
|
|
|
208
|
|
879
|
{ no warnings 'once'; *squish = *squished; } |
|
|
208
|
|
|
|
|
239
|
|
|
|
208
|
|
|
|
|
106464
|
|
|
605
|
|
|
|
|
|
|
sub squished { |
|
606
|
|
|
|
|
|
|
# @last is a single-item array to make tracking undefs saner -> |
|
607
|
7
|
|
|
7
|
1
|
19
|
my (@last, @res); |
|
608
|
7
|
|
|
|
|
4
|
ITEM: for (@{ $_[0] }) { |
|
|
7
|
|
|
|
|
20
|
|
|
609
|
36
|
100
|
|
|
|
63
|
if (!@last) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
# No items seen yet. |
|
611
|
6
|
|
|
|
|
7
|
$last[0] = $_; CORE::push @res, $_; next ITEM |
|
|
6
|
|
|
|
|
6
|
|
|
612
|
6
|
|
|
|
|
9
|
} elsif (!defined $_) { |
|
613
|
|
|
|
|
|
|
# Possibly two undefs in a row: |
|
614
|
4
|
100
|
|
|
|
8
|
next ITEM if not defined $last[0]; |
|
615
|
|
|
|
|
|
|
# .. or not: |
|
616
|
2
|
|
|
|
|
2
|
$last[0] = $_; CORE::push @res, $_; next ITEM |
|
|
2
|
|
|
|
|
2
|
|
|
617
|
2
|
|
|
|
|
2
|
} elsif (!defined $last[0]) { |
|
618
|
|
|
|
|
|
|
# Previous was an undef (but this isn't) |
|
619
|
4
|
|
|
|
|
2
|
$last[0] = $_; CORE::push @res, $_; next ITEM |
|
|
4
|
|
|
|
|
3
|
|
|
620
|
4
|
|
|
|
|
4
|
} |
|
621
|
22
|
100
|
|
|
|
27
|
next ITEM if $_ eq $last[0]; |
|
622
|
17
|
|
|
|
|
13
|
$last[0] = $_; CORE::push @res, $_; |
|
|
17
|
|
|
|
|
17
|
|
|
623
|
|
|
|
|
|
|
} |
|
624
|
7
|
|
|
|
|
12
|
blessed_or_pkg($_[0])->new(@res) |
|
625
|
|
|
|
|
|
|
} |
|
626
|
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
sub uniq { |
|
628
|
5
|
|
|
5
|
1
|
23
|
my %s; |
|
629
|
5
|
|
|
|
|
12
|
blessed_or_pkg($_[0])->new( CORE::grep {; not $s{$_}++ } @{ $_[0] } ) |
|
|
18
|
|
|
|
|
34
|
|
|
|
5
|
|
|
|
|
60
|
|
|
630
|
|
|
|
|
|
|
} |
|
631
|
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
sub repeated { |
|
633
|
3
|
|
|
3
|
1
|
6
|
my %s; |
|
634
|
3
|
|
|
|
|
7
|
blessed_or_pkg($_[0])->new( CORE::grep {; $s{$_}++ == 1 } @{ $_[0] } ) |
|
|
10
|
|
|
|
|
16
|
|
|
|
3
|
|
|
|
|
8
|
|
|
635
|
|
|
|
|
|
|
} |
|
636
|
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
sub sort_by { |
|
638
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
639
|
10
|
|
|
10
|
1
|
593
|
__sort_by( $_[1], @{ $_[0] } ) |
|
|
10
|
|
|
|
|
151
|
|
|
640
|
|
|
|
|
|
|
) |
|
641
|
|
|
|
|
|
|
} |
|
642
|
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
sub nsort_by { |
|
644
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
645
|
7
|
|
|
7
|
1
|
43
|
__nsort_by( $_[1], @{ $_[0] } ) |
|
|
7
|
|
|
|
|
97
|
|
|
646
|
|
|
|
|
|
|
) |
|
647
|
|
|
|
|
|
|
} |
|
648
|
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
sub uniq_by { |
|
650
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
|
651
|
7
|
|
|
7
|
1
|
42
|
__uniq_by( $_[1], @{ $_[0] } ) |
|
|
7
|
|
|
|
|
96
|
|
|
652
|
|
|
|
|
|
|
) |
|
653
|
|
|
|
|
|
|
} |
|
654
|
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
sub flatten_all { |
|
656
|
7
|
|
|
7
|
1
|
39
|
CORE::map {; __flatten_all($_) } @{ $_[0] } |
|
|
17
|
|
|
|
|
22
|
|
|
|
7
|
|
|
|
|
29
|
|
|
657
|
|
|
|
|
|
|
} |
|
658
|
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
sub flatten { |
|
660
|
|
|
|
|
|
|
__flatten( |
|
661
|
|
|
|
|
|
|
( defined $_[1] ? $_[1] : 0 ), |
|
662
|
17
|
100
|
|
17
|
1
|
62
|
@{ $_[0] } |
|
|
17
|
|
|
|
|
42
|
|
|
663
|
|
|
|
|
|
|
) |
|
664
|
|
|
|
|
|
|
} |
|
665
|
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
print |
|
667
|
|
|
|
|
|
|
qq[ My sleeping pattern is cryptographically secure.\n] |
|
668
|
|
|
|
|
|
|
unless caller; |
|
669
|
|
|
|
|
|
|
1; |
|
670
|
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=pod |
|
672
|
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
=head1 NAME |
|
674
|
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
List::Objects::WithUtils::Role::Array - Array manipulation methods |
|
676
|
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
678
|
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
## Via List::Objects::WithUtils::Array -> |
|
680
|
|
|
|
|
|
|
use List::Objects::WithUtils 'array'; |
|
681
|
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
my $array = array(qw/ a b c /); |
|
683
|
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
$array->push(qw/ d e f /); |
|
685
|
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
my @upper = $array->map(sub { uc })->all; |
|
687
|
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
if ( $array->has_any(sub { $_ eq 'a' }) ) { |
|
689
|
|
|
|
|
|
|
... |
|
690
|
|
|
|
|
|
|
} |
|
691
|
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
my $sum = array(1 .. 10)->reduce(sub { $a + $b }); |
|
693
|
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
# See below for full list of methods |
|
695
|
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
## As a Role -> |
|
697
|
|
|
|
|
|
|
use Role::Tiny::With; |
|
698
|
|
|
|
|
|
|
with 'List::Objects::WithUtils::Role::Array'; |
|
699
|
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
701
|
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
A L role defining methods for creating and manipulating ARRAY-type |
|
703
|
|
|
|
|
|
|
objects. |
|
704
|
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
L consumes this role (along with |
|
706
|
|
|
|
|
|
|
L) to provide B object |
|
707
|
|
|
|
|
|
|
methods. |
|
708
|
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
In addition to the methods documented below, these objects provide a |
|
710
|
|
|
|
|
|
|
C method exporting a plain ARRAY-type reference for convenience when |
|
711
|
|
|
|
|
|
|
feeding L or similar, as well as a C method for |
|
712
|
|
|
|
|
|
|
compatibility with L. |
|
713
|
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
=head2 Basic array methods |
|
715
|
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
=head3 new |
|
717
|
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
Constructs a new ARRAY-type object. |
|
719
|
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
=head3 copy |
|
721
|
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
Returns a shallow clone of the current object. |
|
723
|
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
=head3 count |
|
725
|
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
Returns the number of elements in the array. |
|
727
|
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
=head3 defined |
|
729
|
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
Returns true if the element at the specified position is defined. |
|
731
|
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
(Available from v2.13.1) |
|
733
|
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
=head3 end |
|
735
|
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
Returns the last index of the array (or -1 if the array is empty). |
|
737
|
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
=head3 exists |
|
739
|
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
Returns true if the specified index exists in the array. |
|
741
|
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
Negative indices work as you might expect: |
|
743
|
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
my $arr = array(1, 2, 3); |
|
745
|
|
|
|
|
|
|
$arr->set(-2 => 'foo') if $arr->exists(-2); |
|
746
|
|
|
|
|
|
|
# [ 1, 'foo', 3 ] |
|
747
|
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
(Available from v2.13.1) |
|
749
|
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
=head3 is_empty |
|
751
|
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
Returns boolean true if the array is empty. |
|
753
|
|
|
|
|
|
|
|
|
754
|
|
|
|
|
|
|
=head3 is_mutable |
|
755
|
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
Returns boolean true if the hash is mutable; immutable subclasses can override |
|
757
|
|
|
|
|
|
|
to provide a negative value. |
|
758
|
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
=head3 is_immutable |
|
760
|
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
The opposite of L. (Subclasses do not need to override so long as |
|
762
|
|
|
|
|
|
|
L returns a correct value.) |
|
763
|
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
=head3 inflate |
|
765
|
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
my $hash = $array->inflate; |
|
767
|
|
|
|
|
|
|
# Same as: |
|
768
|
|
|
|
|
|
|
# my $hash = hash( $array->all ) |
|
769
|
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
Inflates an array-type object to a hash-type object. |
|
771
|
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
Returns an object of type L; by default this is a |
|
773
|
|
|
|
|
|
|
L. |
|
774
|
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
Throws an exception if the array contains an odd number of elements. |
|
776
|
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
=head3 inflated_type |
|
778
|
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
The class name that objects are blessed into when calling L; |
|
780
|
|
|
|
|
|
|
subclasses can override to provide their own hash-type objects. |
|
781
|
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
Defaults to L. |
|
783
|
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
A consumer returning an C that is not a hash-type object will |
|
785
|
|
|
|
|
|
|
result in undefined behavior. |
|
786
|
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
=head3 scalar |
|
788
|
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
See L. |
|
790
|
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
=head3 unbless |
|
792
|
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
Returns a plain C reference (shallow clone). |
|
794
|
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
=head2 Methods that manipulate the list |
|
796
|
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
=head3 clear |
|
798
|
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
Delete all elements from the array. |
|
800
|
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
Returns the newly-emptied array object. |
|
802
|
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
=head3 delete |
|
804
|
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
Splices a given index out of the array. |
|
806
|
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
Returns the removed value. |
|
808
|
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
=head3 delete_when |
|
810
|
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
$array->delete_when( sub { $_ eq 'foo' } ); |
|
812
|
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
Splices all items out of the array for which the given subroutine evaluates to |
|
814
|
|
|
|
|
|
|
true. |
|
815
|
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
Returns a new array object containing the deleted values (possibly none). |
|
817
|
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
=head3 insert |
|
819
|
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
$array->insert( $position, $value ); |
|
821
|
|
|
|
|
|
|
$array->insert( $position, @values ); |
|
822
|
|
|
|
|
|
|
|
|
823
|
|
|
|
|
|
|
Inserts values at a given position, moving the rest of the array |
|
824
|
|
|
|
|
|
|
rightwards. |
|
825
|
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
The array will be "backfilled" (with undefs) if $position is past the end of |
|
827
|
|
|
|
|
|
|
the array. |
|
828
|
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
Returns the array object. |
|
830
|
|
|
|
|
|
|
|
|
831
|
|
|
|
|
|
|
(Available from v2.12.1) |
|
832
|
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
=head3 pop |
|
834
|
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
Pops the last element off the array and returns it. |
|
836
|
|
|
|
|
|
|
|
|
837
|
|
|
|
|
|
|
=head3 push |
|
838
|
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
Pushes elements to the end of the array. |
|
840
|
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
Returns the array object. |
|
842
|
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
=head3 rotate_in_place |
|
844
|
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
array(1 .. 3)->rotate_in_place; # 2, 3, 1 |
|
846
|
|
|
|
|
|
|
array(1 .. 3)->rotate_in_place(right => 1); # 3, 1, 2 |
|
847
|
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
Rotates the array in-place. A direction can be given. |
|
849
|
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
Also see L, L. |
|
851
|
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
=head3 set |
|
853
|
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
$array->set( $index, $value ); |
|
855
|
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
Takes an array element and a new value to set. |
|
857
|
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
Returns the array object. |
|
859
|
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
=head3 shift |
|
861
|
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
Shifts the first element off the beginning of the array and returns it. |
|
863
|
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
=head3 unshift |
|
865
|
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
Adds elements to the beginning of the array. |
|
867
|
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
Returns the array object. |
|
869
|
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
=head3 splice |
|
871
|
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
# 1- or 2-arg splice (remove elements): |
|
873
|
|
|
|
|
|
|
my $spliced = $array->splice(0, 2) |
|
874
|
|
|
|
|
|
|
# 3-arg splice (replace): |
|
875
|
|
|
|
|
|
|
$array->splice(0, 1, 'abc'); |
|
876
|
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
Performs a C on the current list and returns a new array object |
|
878
|
|
|
|
|
|
|
consisting of the items returned from the splice. |
|
879
|
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
The existing array is modified in-place. |
|
881
|
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
=head3 validated |
|
883
|
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
use Types::Standard -all; |
|
885
|
|
|
|
|
|
|
my $valid = array(qw/foo bar baz/)->validated(Str); |
|
886
|
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
Accepts a L type, against which each element of the current array |
|
888
|
|
|
|
|
|
|
will be checked before being added to a new array. Returns the new array. |
|
889
|
|
|
|
|
|
|
|
|
890
|
|
|
|
|
|
|
If the element fails the type check but can be coerced, the coerced value will |
|
891
|
|
|
|
|
|
|
be added to the new array. |
|
892
|
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
Dies with a stack trace if the value fails type checks and can't be coerced. |
|
894
|
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
(You probably want an B object from |
|
896
|
|
|
|
|
|
|
L instead.) |
|
897
|
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
See: L, L |
|
899
|
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
=head2 Methods that retrieve items |
|
901
|
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
=head3 all |
|
903
|
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
Returns all elements in the array as a plain list. |
|
905
|
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
=head3 bisect |
|
907
|
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
my ($true, $false) = array( 1 .. 10 ) |
|
909
|
|
|
|
|
|
|
->bisect(sub { $_ >= 5 }) |
|
910
|
|
|
|
|
|
|
->all; |
|
911
|
|
|
|
|
|
|
my @bigger = $true->all; # ( 5 .. 10 ) |
|
912
|
|
|
|
|
|
|
my @smaller = $false->all; # ( 1 .. 4 ) |
|
913
|
|
|
|
|
|
|
|
|
914
|
|
|
|
|
|
|
Like L, but creates an array-type object containing two |
|
915
|
|
|
|
|
|
|
partitions; the first contains all items for which the subroutine evaluates to |
|
916
|
|
|
|
|
|
|
true, the second contains items for which the subroutine evaluates to false. |
|
917
|
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
=head3 nsect |
|
919
|
|
|
|
|
|
|
|
|
920
|
|
|
|
|
|
|
my ($first, $second) = array( 1 .. 10 )->nsect(2)->all; |
|
921
|
|
|
|
|
|
|
# array( 1 .. 5 ), array( 6 .. 10 ) |
|
922
|
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
Like L and L, but takes an (integer) number of sets to create. |
|
924
|
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
If there are no items in the list (or no sections are requested), |
|
926
|
|
|
|
|
|
|
an empty array-type object is returned. |
|
927
|
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
If the list divides unevenly, the first set will be the largest. |
|
929
|
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
Inspired by L. |
|
931
|
|
|
|
|
|
|
|
|
932
|
|
|
|
|
|
|
(Available from v2.11.1) |
|
933
|
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
=head3 ssect |
|
935
|
|
|
|
|
|
|
|
|
936
|
|
|
|
|
|
|
my ($first, $second) = array( 1 .. 10 )->ssect(5)->all; |
|
937
|
|
|
|
|
|
|
# array( 1 .. 5 ), array( 6 .. 10 ); |
|
938
|
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
Like L and L, but takes an (integer) target number of items |
|
940
|
|
|
|
|
|
|
per set. |
|
941
|
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
If the list divides unevenly, the last set will be smaller than the specified |
|
943
|
|
|
|
|
|
|
target. |
|
944
|
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
Inspired by L. |
|
946
|
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
(Available from v2.11.1) |
|
948
|
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
=head3 elements |
|
950
|
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
Same as L; included for consistency with similar array-type object |
|
952
|
|
|
|
|
|
|
classes. |
|
953
|
|
|
|
|
|
|
|
|
954
|
|
|
|
|
|
|
=head3 export |
|
955
|
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
Same as L; included for consistency with hash-type objects. |
|
957
|
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
=head3 flatten |
|
959
|
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
Flatten array objects to plain lists, possibly recursively. |
|
961
|
|
|
|
|
|
|
|
|
962
|
|
|
|
|
|
|
C without arguments is the same as L: |
|
963
|
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
my @flat = array( 1, 2, [ 3, 4 ] )->flatten; |
|
965
|
|
|
|
|
|
|
# @flat = ( 1, 2, [ 3, 4 ] ); |
|
966
|
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
If a depth is specified, sub-arrays are recursively flattened until the |
|
968
|
|
|
|
|
|
|
specified depth is reached: |
|
969
|
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
my @flat = array( 1, 2, [ 3, 4 ] )->flatten(1); |
|
971
|
|
|
|
|
|
|
# @flat = ( 1, 2, 3, 4 ); |
|
972
|
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
my @flat = array( 1, 2, [ 3, 4, [ 5, 6 ] ] )->flatten(1); |
|
974
|
|
|
|
|
|
|
# @flat = ( 1, 2, 3, 4, [ 5, 6 ] ); |
|
975
|
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
This works with both ARRAY-type references and array objects: |
|
977
|
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
my @flat = array( 1, 2, [ 3, 4, array( 5, 6 ) ] )->flatten(2); |
|
979
|
|
|
|
|
|
|
# @flat = ( 1, 2, 3, 4, 5, 6 ); |
|
980
|
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
(Specifically, consumers of this role and plain ARRAYs are flattened; other |
|
982
|
|
|
|
|
|
|
ARRAY-type objects are left alone.) |
|
983
|
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
See L for flattening to an unlimited depth. |
|
985
|
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
=head3 flatten_all |
|
987
|
|
|
|
|
|
|
|
|
988
|
|
|
|
|
|
|
Returns a plain list consisting of all sub-arrays recursively |
|
989
|
|
|
|
|
|
|
flattened. Also see L. |
|
990
|
|
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
=head3 get |
|
992
|
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
Returns the array element corresponding to a specified index. |
|
994
|
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
=head3 get_or_else |
|
996
|
|
|
|
|
|
|
|
|
997
|
|
|
|
|
|
|
# Expect to find an object at $pos in $array, |
|
998
|
|
|
|
|
|
|
# or return an empty one if $pos is undef: |
|
999
|
|
|
|
|
|
|
my @keys = $array->get_or_else($pos => hash)->keys->all; |
|
1000
|
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
# Or pass a coderef that provides a default return value; |
|
1002
|
|
|
|
|
|
|
# First arg is the object being operated on: |
|
1003
|
|
|
|
|
|
|
my $item_or_first = $array->get_or_else($pos => sub { shift->get(0) }); |
|
1004
|
|
|
|
|
|
|
# Second arg is the requested index: |
|
1005
|
|
|
|
|
|
|
my $item = $array->get_or_else(3 => sub { |
|
1006
|
|
|
|
|
|
|
my (undef, $pos) = @_; |
|
1007
|
|
|
|
|
|
|
my $created = make_value_for( $pos ); |
|
1008
|
|
|
|
|
|
|
$array->set($pos => $created); |
|
1009
|
|
|
|
|
|
|
$created |
|
1010
|
|
|
|
|
|
|
}); |
|
1011
|
|
|
|
|
|
|
|
|
1012
|
|
|
|
|
|
|
Returns the element corresponding to a specified index; optionally takes a |
|
1013
|
|
|
|
|
|
|
second argument that is used as a default return value if the given index is |
|
1014
|
|
|
|
|
|
|
undef (the array remains unmodified). |
|
1015
|
|
|
|
|
|
|
|
|
1016
|
|
|
|
|
|
|
If the second argument is a coderef, it is invoked on the object (with the |
|
1017
|
|
|
|
|
|
|
requested index as an argument) and its return value is taken as the default. |
|
1018
|
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
=head3 head |
|
1020
|
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
my ($first, $rest) = $array->head; |
|
1022
|
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
In list context, returns the first element of the list, and a new array-type |
|
1024
|
|
|
|
|
|
|
object containing the remaining list. The original object's list is untouched. |
|
1025
|
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
In scalar context, returns just the first element of the array: |
|
1027
|
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
my $first = $array->head; |
|
1029
|
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
=head3 tail |
|
1031
|
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
Similar to L, but returns either the last element and a new array-type |
|
1033
|
|
|
|
|
|
|
object containing the remaining list (in list context), or just the last |
|
1034
|
|
|
|
|
|
|
element of the list (in scalar context). |
|
1035
|
|
|
|
|
|
|
|
|
1036
|
|
|
|
|
|
|
=head3 join |
|
1037
|
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
my $str = $array->join(' '); |
|
1039
|
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
Joins the array's elements and returns the joined string. |
|
1041
|
|
|
|
|
|
|
|
|
1042
|
|
|
|
|
|
|
Defaults to ',' if no delimiter is specified. |
|
1043
|
|
|
|
|
|
|
|
|
1044
|
|
|
|
|
|
|
=head3 kv |
|
1045
|
|
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
Returns an array-type object containing index/value pairs as (unblessed) ARRAYs; |
|
1047
|
|
|
|
|
|
|
this is much like L, except the |
|
1048
|
|
|
|
|
|
|
array index is the "key." |
|
1049
|
|
|
|
|
|
|
|
|
1050
|
|
|
|
|
|
|
=head3 zip |
|
1051
|
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
=head3 mesh |
|
1053
|
|
|
|
|
|
|
|
|
1054
|
|
|
|
|
|
|
my $meshed = array(qw/ a b c /)->mesh( |
|
1055
|
|
|
|
|
|
|
array( 1 .. 3 ) |
|
1056
|
|
|
|
|
|
|
); |
|
1057
|
|
|
|
|
|
|
$meshed->all; # 'a', 1, 'b', 2, 'c', 3 |
|
1058
|
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
Takes array references or objects and returns a new array object consisting of |
|
1060
|
|
|
|
|
|
|
one element from each array, in turn, until all arrays have been traversed |
|
1061
|
|
|
|
|
|
|
fully. |
|
1062
|
|
|
|
|
|
|
|
|
1063
|
|
|
|
|
|
|
You can mix and match references and objects freely: |
|
1064
|
|
|
|
|
|
|
|
|
1065
|
|
|
|
|
|
|
my $meshed = array(qw/ a b c /)->mesh( |
|
1066
|
|
|
|
|
|
|
array( 1 .. 3 ), |
|
1067
|
|
|
|
|
|
|
[ qw/ foo bar baz / ], |
|
1068
|
|
|
|
|
|
|
); |
|
1069
|
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
(C is an alias for C.) |
|
1071
|
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
=head3 part |
|
1073
|
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
my $parts = array( 1 .. 8 )->part(sub { $i++ % 2 }); |
|
1075
|
|
|
|
|
|
|
# Returns array objects: |
|
1076
|
|
|
|
|
|
|
$parts->get(0)->all; # 1, 3, 5, 7 |
|
1077
|
|
|
|
|
|
|
$parts->get(1)->all; # 2, 4, 6, 8 |
|
1078
|
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
Takes a subroutine that indicates into which partition each value should be |
|
1080
|
|
|
|
|
|
|
placed. |
|
1081
|
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
Returns an array-type object containing partitions represented as array-type |
|
1083
|
|
|
|
|
|
|
objects, as seen above. |
|
1084
|
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
Skipped partitions are empty array objects: |
|
1086
|
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
my $parts = array(qw/ foo bar /)->part(sub { 1 }); |
|
1088
|
|
|
|
|
|
|
$parts->get(0)->is_empty; # true |
|
1089
|
|
|
|
|
|
|
$parts->get(1)->is_empty; # false |
|
1090
|
|
|
|
|
|
|
|
|
1091
|
|
|
|
|
|
|
The subroutine is passed the value we are operating on, or you can use the |
|
1092
|
|
|
|
|
|
|
topicalizer C<$_>: |
|
1093
|
|
|
|
|
|
|
|
|
1094
|
|
|
|
|
|
|
array(qw/foo bar baz 1 2 3/) |
|
1095
|
|
|
|
|
|
|
->part(sub { m/^[0-9]+$/ ? 0 : 1 }) |
|
1096
|
|
|
|
|
|
|
->get(1) |
|
1097
|
|
|
|
|
|
|
->all; # 'foo', 'bar', 'baz' |
|
1098
|
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
=head3 part_to_hash |
|
1100
|
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
my $people = array(qw/ann andy bob fred frankie/); |
|
1102
|
|
|
|
|
|
|
my $parts = $people->part_to_hash(sub { ucfirst substr $_, 0, 1 }); |
|
1103
|
|
|
|
|
|
|
$parts->get('A')->all; # 'ann', 'andy' |
|
1104
|
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
Like L, but partitions values into a hash-type object using the result |
|
1106
|
|
|
|
|
|
|
of the given subroutine as the hash key; the values are array-type objects. |
|
1107
|
|
|
|
|
|
|
|
|
1108
|
|
|
|
|
|
|
The returned object is of type L; by default this is a |
|
1109
|
|
|
|
|
|
|
L. |
|
1110
|
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
(Available from v2.23.1) |
|
1112
|
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
=head3 pick |
|
1114
|
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
my $picked = array('a' .. 'f')->pick(3); |
|
1116
|
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
Returns a new array object containing the specified number of elements chosen |
|
1118
|
|
|
|
|
|
|
randomly and without repetition. |
|
1119
|
|
|
|
|
|
|
|
|
1120
|
|
|
|
|
|
|
If the given number is equal to or greater than the number of elements in the |
|
1121
|
|
|
|
|
|
|
list, C will return a shuffled list (same as calling L). |
|
1122
|
|
|
|
|
|
|
|
|
1123
|
|
|
|
|
|
|
(Available from v2.26.1) |
|
1124
|
|
|
|
|
|
|
|
|
1125
|
|
|
|
|
|
|
=head3 random |
|
1126
|
|
|
|
|
|
|
|
|
1127
|
|
|
|
|
|
|
Returns a random element from the array. |
|
1128
|
|
|
|
|
|
|
|
|
1129
|
|
|
|
|
|
|
=head3 reverse |
|
1130
|
|
|
|
|
|
|
|
|
1131
|
|
|
|
|
|
|
Returns a new array object consisting of the reversed list of elements. |
|
1132
|
|
|
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
=head3 roll |
|
1134
|
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
Much like L, but repeated entries in the resultant list are allowed, |
|
1136
|
|
|
|
|
|
|
and the number of entries to return may be larger than the size of the array. |
|
1137
|
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
If the number of elements to return is not specified, the size of the original |
|
1139
|
|
|
|
|
|
|
array is used. |
|
1140
|
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
(Available from v2.26.1) |
|
1142
|
|
|
|
|
|
|
|
|
1143
|
|
|
|
|
|
|
=head3 rotate |
|
1144
|
|
|
|
|
|
|
|
|
1145
|
|
|
|
|
|
|
my $leftwards = $array->rotate; |
|
1146
|
|
|
|
|
|
|
my $rightwards = $array->rotate(right => 1); |
|
1147
|
|
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
Returns a new array object containing the rotated list. |
|
1149
|
|
|
|
|
|
|
|
|
1150
|
|
|
|
|
|
|
Also see L, L. |
|
1151
|
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
=head3 shuffle |
|
1153
|
|
|
|
|
|
|
|
|
1154
|
|
|
|
|
|
|
my $shuffled = $array->shuffle; |
|
1155
|
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
Returns a new array object containing the shuffled list. |
|
1157
|
|
|
|
|
|
|
|
|
1158
|
|
|
|
|
|
|
=head3 sliced |
|
1159
|
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
my $slice = $array->sliced(1, 3, 5); |
|
1161
|
|
|
|
|
|
|
|
|
1162
|
|
|
|
|
|
|
Returns a new array object consisting of the elements retrived |
|
1163
|
|
|
|
|
|
|
from the specified indexes. |
|
1164
|
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
=head3 tuples |
|
1166
|
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
my $tuples = array(1 .. 7)->tuples(2); |
|
1168
|
|
|
|
|
|
|
# Returns: |
|
1169
|
|
|
|
|
|
|
# array( |
|
1170
|
|
|
|
|
|
|
# [ 1, 2 ], |
|
1171
|
|
|
|
|
|
|
# [ 3, 4 ], |
|
1172
|
|
|
|
|
|
|
# [ 5, 6 ], |
|
1173
|
|
|
|
|
|
|
# [ 7 ], |
|
1174
|
|
|
|
|
|
|
# ) |
|
1175
|
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
Returns a new array object consisting of tuples (unblessed ARRAY references) |
|
1177
|
|
|
|
|
|
|
of the specified size (defaults to 2). |
|
1178
|
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
C accepts L types as an optional second parameter; if |
|
1180
|
|
|
|
|
|
|
specified, items in tuples are checked against the type and a coercion is |
|
1181
|
|
|
|
|
|
|
attempted (if available for the given type) if the initial type-check fails: |
|
1182
|
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
use Types::Standard -all; |
|
1184
|
|
|
|
|
|
|
my $tuples = array(1 .. 7)->tuples(2 => Int); |
|
1185
|
|
|
|
|
|
|
|
|
1186
|
|
|
|
|
|
|
A stack-trace is thrown if a value in a tuple cannot be made to validate. |
|
1187
|
|
|
|
|
|
|
|
|
1188
|
|
|
|
|
|
|
As of v2.24.1, it's possible to make the returned tuples blessed array-type |
|
1189
|
|
|
|
|
|
|
objects (of the type of the original class) by passing a boolean true third |
|
1190
|
|
|
|
|
|
|
parameter: |
|
1191
|
|
|
|
|
|
|
|
|
1192
|
|
|
|
|
|
|
# bless()'d tuples, no type validation or coercion: |
|
1193
|
|
|
|
|
|
|
my $tuples = array(1 .. 7)->tuples(2, undef, 'bless'); |
|
1194
|
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
See: L, L |
|
1196
|
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
=head2 Methods that find items |
|
1198
|
|
|
|
|
|
|
|
|
1199
|
|
|
|
|
|
|
=head3 grep |
|
1200
|
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
my $matched = $array->grep(sub { /foo/ }); |
|
1202
|
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
Returns a new array object consisting of the list of elements for which the |
|
1204
|
|
|
|
|
|
|
given subroutine evaluates to true. C<$_[0]> is the element being operated |
|
1205
|
|
|
|
|
|
|
on; you can also use the topicalizer C<$_>. |
|
1206
|
|
|
|
|
|
|
|
|
1207
|
|
|
|
|
|
|
=head3 indexes |
|
1208
|
|
|
|
|
|
|
|
|
1209
|
|
|
|
|
|
|
my $matched = $array->indexes(sub { /foo/ }); |
|
1210
|
|
|
|
|
|
|
|
|
1211
|
|
|
|
|
|
|
If passed a reference to a subroutine, C behaves like L, but |
|
1212
|
|
|
|
|
|
|
returns a new array object consisting of the list of array indexes for which |
|
1213
|
|
|
|
|
|
|
the given subroutine evaluates to true. |
|
1214
|
|
|
|
|
|
|
|
|
1215
|
|
|
|
|
|
|
If no subroutine is provided, returns a new array object consisting of the |
|
1216
|
|
|
|
|
|
|
full list of indexes (like C on an array in perl-5.12+). This feature |
|
1217
|
|
|
|
|
|
|
was added in C. |
|
1218
|
|
|
|
|
|
|
|
|
1219
|
|
|
|
|
|
|
=head3 first_where |
|
1220
|
|
|
|
|
|
|
|
|
1221
|
|
|
|
|
|
|
my $arr = array( qw/ ab bc bd de / ); |
|
1222
|
|
|
|
|
|
|
my $first = $arr->first_where(sub { /^b/ }); ## 'bc' |
|
1223
|
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
Returns the first element of the list for which the given sub evaluates to |
|
1225
|
|
|
|
|
|
|
true. C<$_> is set to each element, in turn, until a match is found (or we run |
|
1226
|
|
|
|
|
|
|
out of possibles). |
|
1227
|
|
|
|
|
|
|
|
|
1228
|
|
|
|
|
|
|
=head3 first_index |
|
1229
|
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
Like L, but return the index of the first successful match. |
|
1231
|
|
|
|
|
|
|
|
|
1232
|
|
|
|
|
|
|
Returns -1 if no match is found. |
|
1233
|
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
=head3 firstidx |
|
1235
|
|
|
|
|
|
|
|
|
1236
|
|
|
|
|
|
|
An alias for L. |
|
1237
|
|
|
|
|
|
|
|
|
1238
|
|
|
|
|
|
|
=head3 last_where |
|
1239
|
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
Like L, but returns the B successful match. |
|
1241
|
|
|
|
|
|
|
|
|
1242
|
|
|
|
|
|
|
=head3 last_index |
|
1243
|
|
|
|
|
|
|
|
|
1244
|
|
|
|
|
|
|
Like L, but returns the index of the B successful match. |
|
1245
|
|
|
|
|
|
|
|
|
1246
|
|
|
|
|
|
|
=head3 lastidx |
|
1247
|
|
|
|
|
|
|
|
|
1248
|
|
|
|
|
|
|
An alias for L. |
|
1249
|
|
|
|
|
|
|
|
|
1250
|
|
|
|
|
|
|
=head3 has_any |
|
1251
|
|
|
|
|
|
|
|
|
1252
|
|
|
|
|
|
|
if ( $array->has_any(sub { $_ eq 'foo' }) ) { |
|
1253
|
|
|
|
|
|
|
... |
|
1254
|
|
|
|
|
|
|
} |
|
1255
|
|
|
|
|
|
|
|
|
1256
|
|
|
|
|
|
|
If passed no arguments, returns boolean true if the array has any elements. |
|
1257
|
|
|
|
|
|
|
|
|
1258
|
|
|
|
|
|
|
If passed a sub, returns boolean true if the sub is true for any element |
|
1259
|
|
|
|
|
|
|
of the array. |
|
1260
|
|
|
|
|
|
|
|
|
1261
|
|
|
|
|
|
|
C<$_> is set to the element being operated upon. |
|
1262
|
|
|
|
|
|
|
|
|
1263
|
|
|
|
|
|
|
=head3 intersection |
|
1264
|
|
|
|
|
|
|
|
|
1265
|
|
|
|
|
|
|
my $first = array(qw/ a b c /); |
|
1266
|
|
|
|
|
|
|
my $second = array(qw/ b c d /); |
|
1267
|
|
|
|
|
|
|
my $intersection = $first->intersection($second); |
|
1268
|
|
|
|
|
|
|
|
|
1269
|
|
|
|
|
|
|
Returns a new array object containing the list of values common between all |
|
1270
|
|
|
|
|
|
|
given array-type objects (including the invocant). |
|
1271
|
|
|
|
|
|
|
|
|
1272
|
|
|
|
|
|
|
The new array object is not sorted in any predictable order. |
|
1273
|
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
(It may be worth noting that an intermediate hash is used; objects that |
|
1275
|
|
|
|
|
|
|
stringify to the same value will be taken to be the same.) |
|
1276
|
|
|
|
|
|
|
|
|
1277
|
|
|
|
|
|
|
=head3 diff |
|
1278
|
|
|
|
|
|
|
|
|
1279
|
|
|
|
|
|
|
my $first = array(qw/ a b c d /); |
|
1280
|
|
|
|
|
|
|
my $second = array(qw/ b c x /); |
|
1281
|
|
|
|
|
|
|
my @diff = $first->diff($second)->sort->all; # (a, d, x) |
|
1282
|
|
|
|
|
|
|
|
|
1283
|
|
|
|
|
|
|
The opposite of L; returns a new array object containing the |
|
1284
|
|
|
|
|
|
|
list of values that are not common between all given array-type objects |
|
1285
|
|
|
|
|
|
|
(including the invocant). |
|
1286
|
|
|
|
|
|
|
|
|
1287
|
|
|
|
|
|
|
The same constraints as L apply. |
|
1288
|
|
|
|
|
|
|
|
|
1289
|
|
|
|
|
|
|
=head3 items_after |
|
1290
|
|
|
|
|
|
|
|
|
1291
|
|
|
|
|
|
|
my $after = array( 1 .. 10 )->items_after(sub { $_ == 5 }); |
|
1292
|
|
|
|
|
|
|
## $after contains [ 6, 7, 8, 9, 10 ] |
|
1293
|
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
Returns a new array object consisting of the elements of the original list |
|
1295
|
|
|
|
|
|
|
that occur after the first position for which the given sub evaluates to true. |
|
1296
|
|
|
|
|
|
|
|
|
1297
|
|
|
|
|
|
|
=head3 items_after_incl |
|
1298
|
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
Like L, but include the item that evaluated to true. |
|
1300
|
|
|
|
|
|
|
|
|
1301
|
|
|
|
|
|
|
=head3 items_before |
|
1302
|
|
|
|
|
|
|
|
|
1303
|
|
|
|
|
|
|
The opposite of L. |
|
1304
|
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
=head3 items_before_incl |
|
1306
|
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
The opposite of L. |
|
1308
|
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
=head2 Methods that iterate the list |
|
1310
|
|
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
=head3 map |
|
1312
|
|
|
|
|
|
|
|
|
1313
|
|
|
|
|
|
|
my $lowercased = $array->map(sub { lc }); |
|
1314
|
|
|
|
|
|
|
# Same as: |
|
1315
|
|
|
|
|
|
|
my $lowercased = $array->map(sub { lc $_[0] }); |
|
1316
|
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
Evaluates a given subroutine for each element of the array, and returns a new |
|
1318
|
|
|
|
|
|
|
array object. C<$_[0]> is the element being operated on; you can also use |
|
1319
|
|
|
|
|
|
|
the topicalizer C<$_>. |
|
1320
|
|
|
|
|
|
|
|
|
1321
|
|
|
|
|
|
|
Also see L. |
|
1322
|
|
|
|
|
|
|
|
|
1323
|
|
|
|
|
|
|
=head3 mapval |
|
1324
|
|
|
|
|
|
|
|
|
1325
|
|
|
|
|
|
|
my $orig = array(1, 2, 3); |
|
1326
|
|
|
|
|
|
|
my $incr = $orig->mapval(sub { ++$_ }); |
|
1327
|
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
$incr->all; # (2, 3, 4) |
|
1329
|
|
|
|
|
|
|
$orig->all; # Still untouched |
|
1330
|
|
|
|
|
|
|
|
|
1331
|
|
|
|
|
|
|
An alternative to L. C<$_> is a copy, rather than an alias to the |
|
1332
|
|
|
|
|
|
|
current element, and the result is retrieved from the altered C<$_> rather |
|
1333
|
|
|
|
|
|
|
than the return value of the block. |
|
1334
|
|
|
|
|
|
|
|
|
1335
|
|
|
|
|
|
|
This feature is borrowed from L by Lukas Mai (CPAN: MAUKE). |
|
1336
|
|
|
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
=head3 natatime |
|
1338
|
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
my $iter = array( 1 .. 7 )->natatime(3); |
|
1340
|
|
|
|
|
|
|
$iter->(); ## ( 1, 2, 3 ) |
|
1341
|
|
|
|
|
|
|
$iter->(); ## ( 4, 5, 6 ) |
|
1342
|
|
|
|
|
|
|
$iter->(); ## ( 7 ) |
|
1343
|
|
|
|
|
|
|
|
|
1344
|
|
|
|
|
|
|
array( 1 .. 7 )->natatime(3, sub { my @vals = @_; ... }); |
|
1345
|
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
Returns an iterator that, when called, produces a list containing the next |
|
1347
|
|
|
|
|
|
|
'n' items. |
|
1348
|
|
|
|
|
|
|
|
|
1349
|
|
|
|
|
|
|
If given a coderef as a second argument, it will be called against each |
|
1350
|
|
|
|
|
|
|
bundled group. |
|
1351
|
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
=head3 rotator |
|
1353
|
|
|
|
|
|
|
|
|
1354
|
|
|
|
|
|
|
my $rot = array(qw/cat sheep mouse/); |
|
1355
|
|
|
|
|
|
|
$rot->(); ## 'cat' |
|
1356
|
|
|
|
|
|
|
$rot->(); ## 'sheep' |
|
1357
|
|
|
|
|
|
|
$rot->(); ## 'mouse' |
|
1358
|
|
|
|
|
|
|
$rot->(); ## 'cat' |
|
1359
|
|
|
|
|
|
|
|
|
1360
|
|
|
|
|
|
|
Returns an iterator that, when called, produces the next element in the array; |
|
1361
|
|
|
|
|
|
|
when there are no elements left, the iterator returns to the start of the |
|
1362
|
|
|
|
|
|
|
array. |
|
1363
|
|
|
|
|
|
|
|
|
1364
|
|
|
|
|
|
|
See also L, L. |
|
1365
|
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
(Available from v2.7.1) |
|
1367
|
|
|
|
|
|
|
|
|
1368
|
|
|
|
|
|
|
=head3 reduce |
|
1369
|
|
|
|
|
|
|
|
|
1370
|
|
|
|
|
|
|
my $sum = array(1,2,3)->reduce(sub { $a + $b }); |
|
1371
|
|
|
|
|
|
|
|
|
1372
|
|
|
|
|
|
|
Reduces the array by calling the given subroutine for each element of the |
|
1373
|
|
|
|
|
|
|
list. C<$a> is the accumulated value; C<$b> is the current element. See |
|
1374
|
|
|
|
|
|
|
L. |
|
1375
|
|
|
|
|
|
|
|
|
1376
|
|
|
|
|
|
|
Prior to C, C<$_[0]> and C<$_[1]> must be used in place of C<$a> and |
|
1377
|
|
|
|
|
|
|
C<$b>, respectively. Using positional arguments may make for cleaner syntax in |
|
1378
|
|
|
|
|
|
|
some cases: |
|
1379
|
|
|
|
|
|
|
|
|
1380
|
|
|
|
|
|
|
my $divide = sub { |
|
1381
|
|
|
|
|
|
|
my ($acc, $next) = @_; |
|
1382
|
|
|
|
|
|
|
$acc / $next |
|
1383
|
|
|
|
|
|
|
}; |
|
1384
|
|
|
|
|
|
|
my $q = $array->reduce($divide); |
|
1385
|
|
|
|
|
|
|
|
|
1386
|
|
|
|
|
|
|
An empty list reduces to C. |
|
1387
|
|
|
|
|
|
|
|
|
1388
|
|
|
|
|
|
|
This is a "left fold" -- B is an alias for L (as of v2.17.1). |
|
1389
|
|
|
|
|
|
|
|
|
1390
|
|
|
|
|
|
|
See also: L |
|
1391
|
|
|
|
|
|
|
|
|
1392
|
|
|
|
|
|
|
=head3 foldr |
|
1393
|
|
|
|
|
|
|
|
|
1394
|
|
|
|
|
|
|
my $result = array(2,3,6)->foldr(sub { $_[1] / $_[0] }); # 1 |
|
1395
|
|
|
|
|
|
|
|
|
1396
|
|
|
|
|
|
|
Reduces the array by calling the given subroutine for each element of the |
|
1397
|
|
|
|
|
|
|
list starting at the end (the opposite of L). |
|
1398
|
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
Unlike L (foldl), the first argument passed to the subroutine is the |
|
1400
|
|
|
|
|
|
|
current element; the second argument is the accumulated value. |
|
1401
|
|
|
|
|
|
|
|
|
1402
|
|
|
|
|
|
|
An empty list reduces to C. |
|
1403
|
|
|
|
|
|
|
|
|
1404
|
|
|
|
|
|
|
(Available from v2.17.1) |
|
1405
|
|
|
|
|
|
|
|
|
1406
|
|
|
|
|
|
|
=head3 visit |
|
1407
|
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
$arr->visit(sub { warn "array contains: $_" }); |
|
1409
|
|
|
|
|
|
|
|
|
1410
|
|
|
|
|
|
|
Executes the given subroutine against each element sequentially; in practice |
|
1411
|
|
|
|
|
|
|
this is much like L, except the return value is thrown away. |
|
1412
|
|
|
|
|
|
|
|
|
1413
|
|
|
|
|
|
|
Returns the original array object. |
|
1414
|
|
|
|
|
|
|
|
|
1415
|
|
|
|
|
|
|
(Available from v2.7.1) |
|
1416
|
|
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
=head2 Methods that sort the list |
|
1418
|
|
|
|
|
|
|
|
|
1419
|
|
|
|
|
|
|
=head3 sort |
|
1420
|
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
my $sorted = $array->sort(sub { $a cmp $b }); |
|
1422
|
|
|
|
|
|
|
|
|
1423
|
|
|
|
|
|
|
Returns a new array object consisting of the list sorted by the given |
|
1424
|
|
|
|
|
|
|
subroutine. |
|
1425
|
|
|
|
|
|
|
|
|
1426
|
|
|
|
|
|
|
Prior to version 2.18.1, positional arguments (C<$_[0]> and C<$_[1]>) must be |
|
1427
|
|
|
|
|
|
|
used in place of C<$a> and C<$b>, respectively. |
|
1428
|
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
=head3 sort_by |
|
1430
|
|
|
|
|
|
|
|
|
1431
|
|
|
|
|
|
|
my $array = array( |
|
1432
|
|
|
|
|
|
|
{ id => 'a' }, |
|
1433
|
|
|
|
|
|
|
{ id => 'c' }, |
|
1434
|
|
|
|
|
|
|
{ id => 'b' }, |
|
1435
|
|
|
|
|
|
|
); |
|
1436
|
|
|
|
|
|
|
my $sorted = $array->sort_by(sub { $_->{id} }); |
|
1437
|
|
|
|
|
|
|
|
|
1438
|
|
|
|
|
|
|
Returns a new array object consisting of the list of elements sorted via a |
|
1439
|
|
|
|
|
|
|
stringy comparison using the given sub. |
|
1440
|
|
|
|
|
|
|
See L. |
|
1441
|
|
|
|
|
|
|
|
|
1442
|
|
|
|
|
|
|
Uses L if available. |
|
1443
|
|
|
|
|
|
|
|
|
1444
|
|
|
|
|
|
|
=head3 nsort_by |
|
1445
|
|
|
|
|
|
|
|
|
1446
|
|
|
|
|
|
|
Like L, but using numerical comparison. |
|
1447
|
|
|
|
|
|
|
|
|
1448
|
|
|
|
|
|
|
=head3 repeated |
|
1449
|
|
|
|
|
|
|
|
|
1450
|
|
|
|
|
|
|
my $repeats = $array->repeated; |
|
1451
|
|
|
|
|
|
|
|
|
1452
|
|
|
|
|
|
|
The opposite of L; returns a new array object containing only repeated |
|
1453
|
|
|
|
|
|
|
elements. |
|
1454
|
|
|
|
|
|
|
|
|
1455
|
|
|
|
|
|
|
(The same constraints apply with regards to stringification; see L) |
|
1456
|
|
|
|
|
|
|
|
|
1457
|
|
|
|
|
|
|
(Available from v2.26.1) |
|
1458
|
|
|
|
|
|
|
|
|
1459
|
|
|
|
|
|
|
=head3 squished |
|
1460
|
|
|
|
|
|
|
|
|
1461
|
|
|
|
|
|
|
my $squished = array(qw/a a b a b b/)->squished; |
|
1462
|
|
|
|
|
|
|
# $squished = array( 'a', 'b', 'a', 'b' ); |
|
1463
|
|
|
|
|
|
|
|
|
1464
|
|
|
|
|
|
|
Similar to L, but only consecutively repeated values are removed from |
|
1465
|
|
|
|
|
|
|
the returned (new) array object. |
|
1466
|
|
|
|
|
|
|
|
|
1467
|
|
|
|
|
|
|
The same constraints as L apply with regards to stringification, but |
|
1468
|
|
|
|
|
|
|
multiple Cs in a row will also be squished. |
|
1469
|
|
|
|
|
|
|
|
|
1470
|
|
|
|
|
|
|
(Available from v2.27.1) |
|
1471
|
|
|
|
|
|
|
|
|
1472
|
|
|
|
|
|
|
=head3 uniq |
|
1473
|
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
my $unique = $array->uniq; |
|
1475
|
|
|
|
|
|
|
|
|
1476
|
|
|
|
|
|
|
Returns a new array object containing only unique elements from the original |
|
1477
|
|
|
|
|
|
|
array. |
|
1478
|
|
|
|
|
|
|
|
|
1479
|
|
|
|
|
|
|
(It may be worth noting that this takes place via an intermediate hash; |
|
1480
|
|
|
|
|
|
|
objects that stringify to the same value are not unique, even if they are |
|
1481
|
|
|
|
|
|
|
different objects. L plus L may help you |
|
1482
|
|
|
|
|
|
|
there.) |
|
1483
|
|
|
|
|
|
|
|
|
1484
|
|
|
|
|
|
|
=head3 uniq_by |
|
1485
|
|
|
|
|
|
|
|
|
1486
|
|
|
|
|
|
|
my $array = array( |
|
1487
|
|
|
|
|
|
|
{ id => 'a' }, |
|
1488
|
|
|
|
|
|
|
{ id => 'a' }, |
|
1489
|
|
|
|
|
|
|
{ id => 'b' }, |
|
1490
|
|
|
|
|
|
|
); |
|
1491
|
|
|
|
|
|
|
my $unique = $array->uniq_by(sub { $_->{id} }); |
|
1492
|
|
|
|
|
|
|
|
|
1493
|
|
|
|
|
|
|
Returns a new array object consisting of the list of elements for which the |
|
1494
|
|
|
|
|
|
|
given sub returns unique values. |
|
1495
|
|
|
|
|
|
|
|
|
1496
|
|
|
|
|
|
|
Uses L if available; falls back to L if not. |
|
1497
|
|
|
|
|
|
|
|
|
1498
|
|
|
|
|
|
|
=head1 NOTES FOR CONSUMERS |
|
1499
|
|
|
|
|
|
|
|
|
1500
|
|
|
|
|
|
|
If creating your own consumer of this role, some extra effort is required to |
|
1501
|
|
|
|
|
|
|
make C<$a> and C<$b> work in sort statements without warnings; an example with |
|
1502
|
|
|
|
|
|
|
a custom exported constructor (and junction support) might look something like: |
|
1503
|
|
|
|
|
|
|
|
|
1504
|
|
|
|
|
|
|
package My::Custom::Array; |
|
1505
|
|
|
|
|
|
|
use strictures 2; |
|
1506
|
|
|
|
|
|
|
require Role::Tiny; |
|
1507
|
|
|
|
|
|
|
Role::Tiny->apply_roles_to_package( __PACKAGE__, |
|
1508
|
|
|
|
|
|
|
qw/ |
|
1509
|
|
|
|
|
|
|
List::Objects::WithUtils::Role::Array |
|
1510
|
|
|
|
|
|
|
List::Objects::WithUtils::Role::Array::WithJunctions |
|
1511
|
|
|
|
|
|
|
My::Custom::Array::Role |
|
1512
|
|
|
|
|
|
|
/ |
|
1513
|
|
|
|
|
|
|
); |
|
1514
|
|
|
|
|
|
|
|
|
1515
|
|
|
|
|
|
|
use Exporter (); |
|
1516
|
|
|
|
|
|
|
our @EXPORT = 'myarray'; |
|
1517
|
|
|
|
|
|
|
sub import { |
|
1518
|
|
|
|
|
|
|
# touch $a/$b in caller to avoid 'used only once' warnings: |
|
1519
|
|
|
|
|
|
|
my $pkg = caller; |
|
1520
|
|
|
|
|
|
|
{ no strict 'refs'; |
|
1521
|
|
|
|
|
|
|
${"${pkg}::a"} = ${"${pkg}::a"}; |
|
1522
|
|
|
|
|
|
|
${"${pkg}::b"} = ${"${pkg}::b"}; |
|
1523
|
|
|
|
|
|
|
} |
|
1524
|
|
|
|
|
|
|
goto &Exporter::import |
|
1525
|
|
|
|
|
|
|
} |
|
1526
|
|
|
|
|
|
|
|
|
1527
|
|
|
|
|
|
|
sub myarray { __PACKAGE__->new(@_) } |
|
1528
|
|
|
|
|
|
|
|
|
1529
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
1530
|
|
|
|
|
|
|
|
|
1531
|
|
|
|
|
|
|
L |
|
1532
|
|
|
|
|
|
|
|
|
1533
|
|
|
|
|
|
|
L |
|
1534
|
|
|
|
|
|
|
|
|
1535
|
|
|
|
|
|
|
L |
|
1536
|
|
|
|
|
|
|
|
|
1537
|
|
|
|
|
|
|
L |
|
1538
|
|
|
|
|
|
|
|
|
1539
|
|
|
|
|
|
|
L |
|
1540
|
|
|
|
|
|
|
|
|
1541
|
|
|
|
|
|
|
L |
|
1542
|
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
L |
|
1544
|
|
|
|
|
|
|
|
|
1545
|
|
|
|
|
|
|
L |
|
1546
|
|
|
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
=head1 AUTHOR |
|
1548
|
|
|
|
|
|
|
|
|
1549
|
|
|
|
|
|
|
Jon Portnoy |
|
1550
|
|
|
|
|
|
|
|
|
1551
|
|
|
|
|
|
|
Portions of this code were contributed by Toby Inkster (CPAN: TOBYINK). |
|
1552
|
|
|
|
|
|
|
|
|
1553
|
|
|
|
|
|
|
Portions of this code are derived from L by Matthew Phillips |
|
1554
|
|
|
|
|
|
|
(MATTP), Graham Knop (HAARG) et al. |
|
1555
|
|
|
|
|
|
|
|
|
1556
|
|
|
|
|
|
|
Portions of this code are inspired by L-0.33 by Adam Kennedy (ADAMK), |
|
1557
|
|
|
|
|
|
|
Tassilo von Parseval, and Aaron Crane. |
|
1558
|
|
|
|
|
|
|
|
|
1559
|
|
|
|
|
|
|
L was inspired by Yanick Champoux in |
|
1560
|
|
|
|
|
|
|
L |
|
1561
|
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
Licensed under the same terms as Perl. |
|
1563
|
|
|
|
|
|
|
|
|
1564
|
|
|
|
|
|
|
=cut |
|
1565
|
|
|
|
|
|
|
|