use strict; use warnings; package Array; use Data::Dumper; sub new { my $class=shift; my $self=bless \@_,$class; $self }; sub grep { my ($self,$code,$pack)=@_; my $ret=defined wantarray ? ref($self)->new() : $self; $pack||=caller; my $sub=ref $code ? $code : eval"package $pack; sub{$code}" or die "grep failed eval: '$code'\n$@"; @$ret=grep($sub->(),@$self); return wantarray ? @$ret : $ret } sub map { my ($self,$code,$pack)=@_; $pack||=caller; my $ret=defined wantarray ? ref($self)->new() : $self; my $sub=ref $code ? $code : eval"package $pack; sub{$code}" or die "map failed eval: '$code'\n$@"; @$ret=map($sub->(),@$self); wantarray ? @$ret : $ret } sub sort { my ($self,$code,$pack)=@_; my $ret=defined wantarray ? ref($self)->new() : $self; $pack||=caller; if ($code) { # we play games with namespaces here because $a and $b are package # variables and we need to do the sort in the same package as the # $a and $b are used in. @$ret=eval qq({ package $pack; local *__sorter=*__sorter=ref \$code ? \$code : eval "sub{\$code}" or die "Sort failed eval: '\$code'\n\$@"; sort __sorter \@\$self; }) or die $@; } else { @$ret=sort @$self; } wantarray ? @$ret : $ret } sub reverse { my $self=shift; my $ret=defined wantarray ? ref($self)->new() : $self; @$ret=reverse @$self; wantarray ? @$ret : $ret }