Why not adopt me?
NAME
Tie::RangeHash - Allows hashes to associate values with a range of keys
REQUIREMENTS
Algorithm::SkipList
is required. Otherwise it uses standard modules.
Installation
Installation is pretty standard:
perl Makefile.PL
make
make test
make install
Note that when you run the tests, you will see warnings. That is intentional.
SYNOPSIS
use Tie::RangeHash;
tie %hash, 'Tie::RangeHash';
$hash{'A,C'} = 1;
$hash{'D,F'} = 2;
$hash{'G,K'} = 3;
$hash{'E'}; # returns '2'
$hash{'BB'}; # returns '1'
$hash{'KL'}; # returns nothing ('undef')
There is also an object-oriented interface:
$hash = new Tie::RangeHash;
$hash->add('A,C', 1);
$hash->add('G,I', 2);
$hash->fetch('H'); # returns '2'
DESCRIPTION
This module allows hashes to associate a value with a range of keys rather than a single key.
For example, you could pass date ranges to the hash and then query it with a specific date, like so:
$cost{'1999-12-15,2000-01-14'} = 150;
$cost{'2000-01-15,2000-02-14'} = 103;
$cost{'2000-02-15,2000-03-14'} = 97;
and then query the cost on a specific date:
$this_cost = $cost{'2000-02-08'};
Numeric key ranges can also be used:
tie %hash, 'Tie::RangeHash', {
Type => Tie::RangeHash::TYPE_NUMBER
};
$hash{'1.4,1.8'} = 'Jim';
$hash{'1.0,1.399999'} = 'Ned';
$hash{'1.800001,2.0'} = 'Boo';
Custom comparison routines to support alternate datatypes can be implemented by specifying a new node type for Algorithm::SkipList
.
Information to be added.
Object-Oriented Interface
Tie::RangeHash
has an object-oriented interface as an alternative to using a tied hash.
- new
-
Creates a new object.
$OBJ = Tie::RangeHash->new( %ATTR );
%ATTR
is a hash containing the attributes described above. This is the same as theTIEHASH
method used for tied hashes. - add
-
Adds a new key/value pair to the object.
$OBJ->add( $KEY, $VALUE );
$KEY
may be a string value in the form oflow,high
or an array reference in the form of[ low, high ]
. This is the same as theSTORE
method used for tied hashes. - fetch
-
$VALUE = $OBJ->fetch( $KEY );
Returns the value associated with
$KEY
. ($KEY
may be in the form oflow,high
or a key betweenlow
andhigh
.) This is the same as theFETCH
method used for tied hashes. - fetch_key
-
$REAL_KEY = $OBJ->fetch( $KEY ); ($REAL_KEY, $VALUE) = $OBJ->fetch( $KEY );
Like
fetch
, but it returns the key range that was matched rather than the value. If it is called in an array context, it will return the key and value. - key_exists
-
if ($OBJ->key_exists( $KEY )) { .. }
Returns
true
if$KEY
has been defined (even if the value isundef
). ($KEY
is in the same form as is used by thefetch
method.) This is the same as theEXISTS
method used for tied hashes.It is called
key_exists
so as not to be confused with theexists
keyword in Perl. - clear
-
$OBJ->clear();
Deletes all keys and values defined in the object. This is the same as the
CLEAR
method used for tied hashes. - remove
-
$VALUE = $OBJ->remove( $KEY );
Deletes the
$KEY
from the object and returnes the associated value. ($KEY
is in the same form as is used by thefetch
method.) If$KEY
is not the exactlow,high
range, a warning will be emitted. This is the same as theDELETE
method used for tied hashes.It is called
remove
so as not to be confused with thedelete
keyword in Perl. - first_key
-
$KEY = $OBJ->first_key();
- next_key
-
$KEY = $OBJ->next_key($LAST_KEY);
Implementation Notes
Internally, the hash uses skip lists. Skip lists are an alternative to binary trees. For more information, see Algorithm::SkipList
.
KNOWN ISSUES
The is a new version of the module and has behaves differently compared to older versions. This is due to using the Algorithm::SkipList
module for maintaining the underlying data rather than re-implementing it. While this improves the maintainability with the code, it increases incompatability with previous versions.
Some of the changes include:
- Overlapping keys cause fatal errors instead of warnings
-
Because the key comparison is now performed in the skip list node, there is no obvious way for it to give a warning and return a meaningful result. So instead the code dies. If you code relies on the possibility of using overlapping keys, then it may be more appropriate to have it test the code:
eval { $hash{'111,999'} = $value; };
This error can also occur by merely testing a hash, so it is important to run some checks if you are testing hash ranges:
eval { if ($hash{'111,999'} == $value) { ... } }
- Keys can be redefined
-
Nodes can now be redefined. For example:
$hash{'1,3'} = $value; ... $hash{'1,3'} = $new_value; ... $hash{'2'} = $new_value;
Note that a range is no longer required.
- Non-range keys can be added.
-
When inserting a key,
$hash{'x'}
will be treated like$hash{'x,x'}
. - Open-ended ranges are allowed.
-
Open ended ranges are now supported. So the following can be added:
$hash{',10'} = $upper_bound; $hash{'11,'} = $lower_bound;
- array references can no longer be keys.
-
The following is not supported anymore:
$hash{ \@array ) = $value;
- warnings no longer registered.
-
Warning registration is no longer used. This may change in the future.
- Custom separators and comparisons are not supported.
-
Only commas can be used as separators.
To customize separators and comparisons, you will have to specify a custom
Algorithm::SkipList::Node
method.
See the Changes file for a more complete list of incompatabilities.
If your code does not rely on these quirks, then you should be able to substitute with no problems.
SEE ALSO
A module with similar functionality for numerical values is Array::IntSpan
.
Algorithm::SkipList
for more information on skip lists.
AUTHOR
Robert Rothenberg <rrwo at cpan.org>
Acknowledgements
Charles Huff <charleshuff atdecisionresearch.com> for suggestions and bug reports.
Sam Tregar <sam at tregar.com> for optimization suggestions.
Various Perl Monks <http://www.perlmonks.org> for advice and code snippets.
Suggestions and Bug Reporting
Feedback is always welcome. Please use the CPAN Request Tracker at http://rt.cpan.org to submit bug reports.
LICENSE
Copyright (C) 2000-2004 Robert Rothenberg. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.