NAME

Data::Hive - convenient access to hierarchical data

VERSION

version 1.010

SYNOPSIS

use Data::Hive;

my $hive = Data::Hive->NEW(\%arg);

$hive->foo->bar->quux->SET(17);

print $hive->foo->bar->quux->GET;  # 17

DESCRIPTION

Data::Hive doesn't do very much. Its main purpose is to provide a simple, consistent interface for accessing simple, nested data dictionaries. The mechanism for storing or consulting these dictionaries is abstract, so it can be replaced without altering any of the code that reads or writes the hive.

A hive is like a set of nested hash references, but with a few crucial differences:

  • a hive is always accessed by methods, never by dereferencing with ->{}

    For example, these two lines perform similar tasks:

    $href->{foo}->{bar}->{baz}
    
    $hive->foo->bar->baz->GET
  • every key may have a value as well as children

    With nested hashrefs, each entry is either another hashref (representing children in the tree) or a leaf node. With a hive, each entry may be either or both. For example, we can do this:

    $hive->entry->SET(1);
    
    $hive->entry->child->SET(1)

    This wouldn't be possible with a hashref, because $href->{entry} could not hold both another node and a simple value.

    It also means that along the ways to existing values in a hive, there might be paths with no existing value.

    $hive->NEW(...);                  # create a new hive with no entries
    
    $hive->foo->bar->baz->SET(1);     # set a single value
    
    $hive->foo->EXISTS;               # false!  no value exists here
    
    grep { 'foo' eq $_ } $hive->KEYS; # true!   we can descent down this path
    
    $hive->foo->bar->baz->EXISTS;     # true!   there is a value here
  • hives are accessed by path, not by name

    When you call $hive->foo->bar->baz->GET, you're not accessing several substructures. You're accessing one hive. When the GET method is reached, the intervening names are converted into an entry path and that is accessed. Paths are made of zero or more non-empty strings. In other words, while this is legal:

    $href->{foo}->{''}->baz;

    It is not legal to have an empty part in a hive path.

WHY??

By using method access, the behavior of hives can be augmented as needed during testing or development. Hives can be easily collapsed to single key/value pairs using simple notations whereby $hive->foo->bar->baz->SET(1) becomes $storage->{"foo.bar.baz"} = 1 or something similar.

This, along with the Data::Hive::Store API makes it very easy to swap out the storage and retrieval mechanism used for keeping hives in persistent storage. It's trivial to persist entire hives into a database, flatfile, CGI query, or many other structures, without using weird tricks beyond the weird trick that is Data::Hive itself.

METHODS

hive path methods

All lowercase methods are used to travel down hive paths.

When you call $hive->some_name, the return value is another Data::Hive object using the same store as $hive but with a starting path of some_name. With that hive, you can descend to deeper hives or you can get or set its value.

Once you've reached the path where you want to perform a lookup or alteration, you call an all-uppercase method. These are detailed below.

hive access methods

These methods are thin wrappers around required modules in Data::Hive::Store subclasses. These methods all basically call a method on the store with the same (but lowercased) name and pass it the hive's path.

NEW

This constructs a new hive object. Note that the name is NEW and not new! The new method is just another method to pick a hive path part.

The following are valid arguments for NEW.

store

a Data::Hive::Store object, or one with a compatible interface; this will be used as the hive's backend storage driver; do not supply store_class or store_args if store is supplied

store_class

This names a class from which to instantiate a storage driver. The classname will have Data::Hive::Store:: prepended; to avoid this, prefix it with a '=' (=My::Store). A plus sign can be used instead of an equal sign, for historical reasons.

store_args

If store_class has been provided instead of store, this argument may be given as an arrayref of arguments to pass (dereferenced) to the store class's new method.

GET

my $value = $hive->some->path->GET( $default );

The GET method gets the hive value. If there is no defined value at the path and a default has been supplied, the default will be returned instead.

$default should be a simple scalar or a subroutine. If $default is a subroutine, it will be called to compute the default only if needed. The behavior for other types of defaults is undefined.

overloading

Hives are overloaded for stringification and numification so that they behave like their value when used without an explicit GET. This behavior is deprecated and will be removed in a future release. Always use GET to get the value of a hive.

SET

$hive->some->path->SET(10);

This method sets (replacing, if necessary) the hive value.

Data::Hive was built to store simple scalars as values. Although it probably works just fine with references in the hive, it has not been tested for such use, and there may be bugs lurking in there.

SET's return value is not defined.

EXISTS

if ($hive->foo->bar->EXISTS) { ... }

This method tests whether a value (even an undefined one) exists for the hive.

DELETE

$hive->foo->bar->DELETE;

This method deletes the hive's value. The deleted value is returned. If no value had existed, undef is returned.

DELETE_ALL

This method behaves like DELETE, but all values for paths below the current one will also be deleted.

KEYS

my @keys = $hive->KEYS;

This returns a list of next-level path elements that exist. For example, given a hive with values for the following paths:

foo
foo/bar
foo/bar/baz
foo/xyz/abc
foo/xyz/def
foo/123

This shows the expected results:

keys of      | returns
-------------+------------
foo          | bar, xyz, 123
foo/bar      | baz
foo/bar/baz  |
foo/xyz      | abc, def
foo/123      |

COPY_ONTO

$hive->foo->COPY_ONTO( $another_hive->bar );

This method copies all the existing values found at or under the current path to another Data::Hive, using either the same or a different store.

Currently, this will set each found value individually. In the future, store classes should have the ability to receive a bulk-set message to operate in a transaction, if appropriate.

HIVE

$hive->HIVE('foo');          #  equivalent to $hive->foo

$hive->HIVE('foo', 'bar');   #  equivalent to $hive->foo->bar

This method returns a subhive of the current hive. In most cases, it is simpler to use the lowercase hive access method. This method is useful when you must, for some reason, access an entry whose name is not a valid Perl method name.

It is also needed if you must access a path with the same name as a method in UNIVERSAL. In general, only import, isa, and can should fall into this category, but some libraries unfortunately add methods to UNIVERSAL. Common offenders include moniker, install_sub, reinstall_sub.

This method should be needed fairly rarely. It may also be called as ITEM for historical reasons.

NAME

This method returns a name that can be used to represent the hive's path. This name is store-dependent, and should not be relied upon if the store may change. It is provided primarily for debugging.

ROOT

This returns a Data::Hive object for the root of the hive.

SAVE

This method tells the hive store to save the value (or lack thereof) for the current path. For many stores, this does nothing. For hive stores that are written out only on demand, this method must be called.

SAVE_ALL

This method tells the hive store to save the value (or lack thereof) for the current path and all paths beneath it. For many stores, this does nothing. For hive stores that are written out only on demand, this method must be called.

STORE

This method returns the storage driver being used by the hive.

AUTHORS

  • Hans Dieter Pearcey <hdp@cpan.org>

  • Ricardo Signes <rjbs@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2006 by Hans Dieter Pearcey.

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