[code-review] Tie::Array::Sorted
Simon Cozens <simon-eH/[email protected]> Wed, 12 Nov 2003 14:54:47 +0000
| Newsgroups | gmane.comp.lang.perl.code-review-ladder |
|---|---|
| Message-ID | <[email protected]> |
--k1lZvvs/B4yU6o8G
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
It's time I practiced what I preached; here's my latest module, before it goes
to CPAN.
Simon
--
print "Just another ",0 ? "Ruby" : "Perl", " double agent\n"
--k1lZvvs/B4yU6o8G
Content-Type: application/x-perl
Content-Disposition: attachment; filename="Sorted.pm"
Content-Transfer-Encoding: quoted-printable
package Tie::Array::Sorted;=0Ause base 'Tie::Array';=0Ause 5.006;=0Ause str=
ict;=0Ause warnings;=0Aour $VERSION =3D '1.0';=0A=0A=3Dhead1 NAME=0A=0ATie:=
:Array::Sorted - An array which is kept sorted=0A=0A=3Dhead1 SYNOPSIS=0A=0A=
use Tie::Array::Sorted;=0A tie @a, "Tie::Array::Sorted";=0A push @a, 10=
, 4, 7, 3, 4;=0A print "@a"; # "3 4 4 7 10"=0A=0A=3Dhead1 DESCRIPTION=0A=
=0AThis presents an ordinary array, but is kept sorted. All pushes and=0Aun=
shifts cause the elements in question to be inserted in the=0Aappropriate l=
ocation to maintain order.=0A=0ADirect stores (C<$a[10] =3D "wibble">) effe=
ctively splice out the original=0Avalue and insert the new element. It's no=
t clear why you'd want to use=0Adirect stores like that, but this module do=
es the right thing if you do.=0A=0AIf you don't like the ordinary numeric c=
omparator, you can provide your=0Aown; it should compare the two elements i=
t is given:=0A=0A tie @a, "tie::Array::Sorted", sub { $_[0] cmp $_[1] }=
=0A=0A=3Dcut=0A=0Asub TIEARRAY { =0A my ($class, $comparator) =3D @_;=
=0A bless {=0A array =3D> [],=0A comp =3D> (defined $comp=
arator ? $comparator : sub { $_[0] <=3D> $_[1] })=0A }, $class;=0A}=0A=
=0Asub STORE {=0A my ($self, $index, $elem) =3D @_;=0A splice @{$self=
->{array}}, $index, 0;=0A $self->PUSH($elem);=0A}=0A=0Asub PUSH { =0A =
my ($self, @elems) =3D @_;=0A ELEM: for my $elem (@elems) {=0A m=
y ($lo, $hi) =3D (0, $#{$self->{array}});=0A while ($hi >=3D $lo) {=
=0A my $mid =3D int(($lo+$hi)/2);=0A my $mid_val =3D =
$self->{array}[$mid];=0A my $cmp =3D $self->{comp}($elem, $mid_v=
al);=0A if ($cmp =3D=3D 0) {=0A splice(@{$self->{=
array}}, $mid, 0, $elem);=0A next ELEM;=0A } elsi=
f ($cmp > 0) { $lo =3D $mid + 1 }=0A elsif ($cmp < 0) { $hi =3D =
$mid - 1 }=0A }=0A splice(@{$self->{array}}, $lo, 0, $elem);=
=0A }=0A}=0A=0Asub UNSHIFT { goto &PUSH }=0A=0Asub FETCHSIZE { scalar @{=
$_[0]->{array}} }=0Asub STORESIZE { $#{$_[0]->{array}} =3D $_[1]-1 }=0Asub =
FETCH { $_[0]->{array}->[$_[1]] }=0Asub CLEAR { @{$_[0]->{array}} =
=3D () }=0Asub POP { pop(@{$_[0]->{array}}) }=0Asub SHIFT { shift=
(@{$_[0]->{array}}) }=0A=0Asub EXISTS { exists $_[0]->{array}->[$_[1]] }=
=0Asub DELETE { delete $_[0]->{array}->[$_[1]] }=0A=0A1;=0A=0A=3Dhead1 A=
UTHOR=0A=0ASimon Cozens, E<lt>simon-LhsUWLkCAQ8b/[email protected]<gt>=0A=0A=3Dhead1 COPYRIGHT =
AND LICENSE=0A=0ACopyright 2003 by Kasei=0A=0AThis library is free software=
; you can redistribute it and/or modify=0Ait under the same terms as Perl i=
tself. =0A=0A=3Dcut=0A
--k1lZvvs/B4yU6o8G--