NAME

Array::AsHash - Treat arrays as a hashes, even if you need references for keys.

VERSION

Version 0.02

SYNOPSIS

 use Array::AsHash;

 my $array = Array::AsHash->new({
     array => \@array,
     clone => 1, # optional
 });

 while (my ($key, $value) = $array->each) {
     # sorted
     ...
 }

 my $value = $array->get($key);
 $array->put($key, $value);
 
 if ( $array->exists($key) ) {
     ...
 }

 $array->delete($key);

DESCRIPTION

Sometimes we have an array that we need to treat as a hash. We need the data ordered, but we don't use an ordered hash because it's already an array. Or it's just quick 'n easy to run over array elements two at a time.

Because we take a reference to what you pass to the constructor (or use the reference you pass), you may wish to copy your data if you do not want it altered (the data are not altered except through the publicly available methods of this class).

Also, we keep the array an array. This does mean that things might get a bit slow if you have a large array, but it also means that you can use references (including objects) as "keys". For the general case of fetching and storing items, however, you'll find the operations are O(1). Behaviors which can affect the entire array are often O(N).

EXPORT

None.

OVERLOADING

Note that the boolean value of the object has been overloaded. An empty array object will report false in boolean context:

my $array = Array::AsHash->new;
if ($array) {
  # never gets here
}

METHODS

new

my $array = Array::AsHash->new( { array => \@array } );

Returns a new Array::AsHash object. If an array is passed to new, it must contain an even number of elements. This array will be treated as a set of key/value pairs:

my @array = qw/foo bar one 1/;
my $array = Array::AsHash->new({array => \@array});
print $array->get('foo'); # prints 'bar'

Note that the array is stored internally and changes to the Array::AsHash object will change the array that was passed to the constructor as an argument. If you do not wish this behavior, clone the array beforehand or ask the constructor to clone it for you.

my $array = Array::AsHash->new(
   {
       array => \@array,
       clone => 1, # optional
   }
);

Internally, we use the Clone module to clone the array. This will not always work if you are attempting to clone objects (inside-out objects are particularly difficult to clone). If you encounter this, you will need to clone the array yourself. Most of the time, however, it should work.

Of course, you can simply create an empty object and it will still work.

my $array = Array::AsHash->new;
$array->put('foo', 'bar');

keys

my @keys = $array->keys;

Returns the "keys" of the array. Returns an array reference in scalar context.

values

my @values = $array->values;

Returns the "values" of the array. Returns an array reference in scalar context.

delete

my @values = $array->delete(@keys);

Deletes the given @keys from the array. Returns the values of the deleted keys. In scalar context, returns an array reference of the keys.

As a "common-case" optimization, if only one key is requested for deletion, deletion in scalar context will result in the one value (if any) being returned instead of an array reference.

my $deleted = $array->delete($key); # returns the value for $key
my $deleted = $array->delete($key1, $key2); # returns an array reference

Non-existing keys will be silently ignored.

each

while ( my ($key, $value) = $array->each ) {
   # iterate over array like a hash
}

Lazily returns keys and values, in order, until no more are left. Every time each() is called, will automatically increment to the next key value pair. If no more key/value pairs are left, will reset itself to the first key/value pair.

As with a regular hash, if you do not iterate over all of the data, the internal pointer will be pointing at the next key/value pair to be returned. If you need to restart from the beginning, call the reset_each method.

kv

while ( my ($key, $value) = $array->kv ) {
   # iterate over array like a hash
}

kv is a synonym for each.

reset_each

$array->reset_each;

Resets the each iterator to point to the beginning of the array.

exists

if ($array->exists($thing)) { ... }

Returns true if the given $thing exists in the array as a key.

get_array

my @array = $array->get_array;

Returns the array in the object. Returns an array reference in scalar context.

get

my $value = $array->get($key);

Returns the value associated with a given key, if any.

put

$array->put($key, $value);

Sets the value for a given $key. If the key does not already exist, this pushes two elements onto the end of the array.

insert_before

$array->insert_before($key, @kv_pairs);

This method takes a given $key and attempts to insert an even-sized list of key/value pairs before the given key. Will croak if $key does not exist or if @kv_pairs is not an even-sized list.

$array->insert_before($key, this => 'that', one => 1);

insert_after

$array->insert_after($key, @kv_pairs);

This method takes a given $key and attempts to insert an even-sized list of key/value pairs after the given key. Will croak if $key does not exist or if @kv_pairs is not an even-sized list.

$array->insert_after($key, this => 'that', one => 1);

clone

my $array2 = $array->clone;

Attempts to clone (deep copy) and return a new object. This may fail if the array contains objects which Clone cannot handle.

WHY NOT A TIED HASH?

You may very well find that a tied hash fits your purposes better and there's certainly nothing wrong with them. Personally, I do not use tied variables unless absolutely necessary because ties are frequently buggy, they tend to be slow and they take a perfectly ordinary variable and make it hard to maintain. Return a tied variable and some poor maintenance programmer is just going to see an hash and they'll get awfully confused when their code isn't doing quite what they expect.

Of course, this module provides a richer interface than a tied hash would, but that's just another benefit of using a proper class instead of a tie.

AUTHOR

Curtis "Ovid" Poe, <ovid@cpan.org>

BUGS

Please report any bugs or feature requests to bug-array-ashash@rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Array-AsHash. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SEE ALSO

Clone, Tie::IxHash, Class::Std (how this module is implemented).

COPYRIGHT & LICENSE

Copyright 2005 Curtis "Ovid" Poe, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.