Commit | Line | Data |
78ba4051 |
1 | package DOM::Tiny::_Collection; |
2 | |
3 | use strict; |
4 | use warnings; |
5 | use Carp 'croak'; |
6 | use List::Util; |
7 | use Scalar::Util 'blessed'; |
8 | |
8398aa8a |
9 | our $VERSION = '0.002'; |
78ba4051 |
10 | |
78ba4051 |
11 | sub new { |
12 | my $class = shift; |
13 | return bless [@_], ref $class || $class; |
14 | } |
15 | |
16 | sub TO_JSON { [@{shift()}] } |
17 | |
18 | sub compact { |
19 | my $self = shift; |
20 | return $self->new(grep { defined && (ref || length) } @$self); |
21 | } |
22 | |
23 | sub each { |
24 | my ($self, $cb) = @_; |
25 | return @$self unless $cb; |
26 | my $i = 1; |
27 | $_->$cb($i++) for @$self; |
28 | return $self; |
29 | } |
30 | |
31 | sub first { |
32 | my ($self, $cb) = (shift, shift); |
33 | return $self->[0] unless $cb; |
34 | return List::Util::first { $_ =~ $cb } @$self if ref $cb eq 'Regexp'; |
35 | return List::Util::first { $_->$cb(@_) } @$self; |
36 | } |
37 | |
38 | sub flatten { $_[0]->new(_flatten(@{$_[0]})) } |
39 | |
40 | sub grep { |
41 | my ($self, $cb) = (shift, shift); |
42 | return $self->new(grep { $_ =~ $cb } @$self) if ref $cb eq 'Regexp'; |
43 | return $self->new(grep { $_->$cb(@_) } @$self); |
44 | } |
45 | |
46 | sub join { |
2d9f5165 |
47 | join +(defined($_[1]) ? $_[1] : ''), map {"$_"} @{$_[0]}; |
78ba4051 |
48 | } |
49 | |
50 | sub last { shift->[-1] } |
51 | |
52 | sub map { |
53 | my ($self, $cb) = (shift, shift); |
54 | return $self->new(map { $_->$cb(@_) } @$self); |
55 | } |
56 | |
57 | sub reduce { |
58 | my $self = shift; |
59 | @_ = (@_, @$self); |
60 | goto &List::Util::reduce; |
61 | } |
62 | |
63 | sub reverse { $_[0]->new(reverse @{$_[0]}) } |
64 | |
65 | sub shuffle { $_[0]->new(List::Util::shuffle @{$_[0]}) } |
66 | |
67 | sub size { scalar @{$_[0]} } |
68 | |
69 | sub slice { |
70 | my $self = shift; |
71 | return $self->new(@$self[@_]); |
72 | } |
73 | |
74 | sub sort { |
75 | my ($self, $cb) = @_; |
76 | |
77 | return $self->new(sort @$self) unless $cb; |
78 | |
79 | my $caller = caller; |
80 | no strict 'refs'; |
81 | my @sorted = sort { |
82 | local (*{"${caller}::a"}, *{"${caller}::b"}) = (\$a, \$b); |
83 | $a->$cb($b); |
84 | } @$self; |
85 | return $self->new(@sorted); |
86 | } |
87 | |
88 | sub tap { |
89 | my ($self, $cb) = (shift, shift); |
90 | $_->$cb(@_) for $self; |
91 | return $self; |
92 | } |
93 | |
94 | sub to_array { [@{shift()}] } |
95 | |
96 | sub uniq { |
97 | my ($self, $cb) = (shift, shift); |
98 | my %seen; |
99 | return $self->new(grep { !$seen{$_->$cb(@_)}++ } @$self) if $cb; |
100 | return $self->new(grep { !$seen{$_}++ } @$self); |
101 | } |
102 | |
103 | sub _flatten { |
104 | map { _ref($_) ? _flatten(@$_) : $_ } @_; |
105 | } |
106 | |
107 | sub _ref { ref $_[0] eq 'ARRAY' || blessed $_[0] && $_[0]->isa(__PACKAGE__) } |
108 | |
109 | 1; |
9a5f1e3f |
110 | |
111 | =for Pod::Coverage *EVERYTHING* |
112 | |
113 | =cut |