RFC: New module Tie::HashCustomStorage

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!


As part of the work I've done for Class::MakeMethods, I've written a
tied hash class which makes it easy to also specify a custom storage
for the hash.

In other words you can get:
- a tied hash of tied scalar
- a tied hash of object
- a tied hash of value with automatic initialization

As I wrote the doc, I realized that it may be useful outside of
Class::MakeMethods. So if people are interested, I will release
Tie::HashCustomStorage as a stand-alone module. If not, it will stay
within Class::MakeMethods.

You will find below the doc of this module (note that it refers to the
old module name Class::MakeMethods::Utility::TieHash).

I can also provide an equivalent module for tied arrays.

Comments are always welcome. (especially regarding the module name)



    Class::MakeMethods::Utility::TieHash - Tie hash and value storage

      tie %hash , 'Class::MakeMethods::Utility::TieHash',
         tie_hash => 'My_Tie_Hash', |
         tie_hash => [ 'My_Tie_Hash' , @my_args ],
       ] ,

         init_storage => \&my_sub, |
         init_storage => [ \&my_sub, @my_args ], |
         tie_storage => 'MyTieScalar' , |
         tie_storage => [ 'MyTieScalar', @my_args], |
         class_storage => 'MyClass' , |
         class_storage => [ 'MyClass' , @my_args ],
       [ autovivify => [ 0 | 1 ] ]

    This module provides a kind of a proxy tied hash. By default (without
    any constructor parameter), this class provides a regular hash.

    With a "tie_hash" parameter (and a tied hash class provided by the
    user), this class provides a regular tied hash (as usual). All "STORE"
    and "FETCH" call are delegated to the user tied hash class.

    With a "tie_storage" parameter (and a tied scalar class), all value of
    the hash are tied to the tied scalar class passed by the user. This way,
    you can get a hash of tied scalars.

    With a "class_storage" parameter (and a class name), you get a strongly
    typed hash where value can only be instance of the class passed with the
    "class_storage" parameter. This object can be autovivified or not
    depending on the value of <autovivify> parameter.

    With a "init_storage" parameter (and a sub ref), you get a regular hash
    where all value are initialized with the passed sub.

    By combining "tie_hash" parameter with one of the *_storage parameter,
    you can get a tied hash of tied scalars, or a tied hash of objects or a
    tied hash with auto-initialized values.

What's going on here ?
    When the user calls "tie %hash ,
    'Class::MakeMethods::Utility::TieHash'", a tied hash is created, let's
    call it a *proxy hash*.

    To let the user define its own hash behavior, the proxy hash contains a
    hash that will be tied by the user class when the proxy hash is created
    with a "tie_hash" parameters. Let's call it the *user hash*.

    The values of the user hash will contain the data that the user care
    about. These scalar values are contained in the *storage* of the user

    This storage of the user hash can also be specialized by using the
    "tie_storage" parameter or the "class_storage" parameter or the
    "init_storage" parameter.

    Parameters are:

    tie_hash => "Tie::MyHash"
        The class to tie the user hash.

    tie_storage => "Tie::MyScalar"
        The class to tie to the scalars contained in the user hash.

    class_storage => "My::Class"
        All scalar contained in the values of the user hash will be
        instances of "class_storage"

    autovivify [ 0 | 1 ]
        When fetched, the value of the user hash will be automatically
        initialized with and instance of "class_storage". (this parameter
        can only be used with "class_storage"). Default is 1.

    init_storage => sub { ... }
        When fetched, the value of the user hash will be automatically
        initialized by calling this subroutine and storing its return value
        into the user hash.

        The sub ref will be called with one parameter: the index of the
        fetched item.

        I.e., calling $hash will perform:

         $hash = $init_storage->('foo') ;

Requirement regarding "tie_hash" class
    Automatic tying of the scalar contained by the hash means the the tying
    must be done on the actual scalar storage. For a standard hash this
    variable is "$self-">. For a tied hash, this scalar storage
    is actually contained in a class provided by the user through the
    "tie_hash" parameter.

    The user class passed through the "tie_hash" parameter must satisfy one
    of the following conditions:

    *   Inherit from Tie::StdHash

    *   Store its data in "$self->" or "$self->"

    *   Provide a "get_data_ref" method that will return a ref of the hash
        containing the data.

      # create a hash where value are initialized with a sub and arguments
      tie %hash, 'Class::MakeMethods::Utility::TieHash',
        init => [ \&my_sub, @my_args ] ;

      # create a regular tied hash. This is equivalent to
      # tie %hash, 'My_Tie_Hash';
      tie %hash, 'Class::MakeMethods::Utility::TieHash',
        tie_hash => 'My_Tie_Hash' ;

      # create a regular tied hash. This is equivalent to
      # tie %hash, 'My_Tie_Hash', foo => 'bar' ;
      tie %hash, 'Class::MakeMethods::Utility::TieHash',
        tie_hash => [ 'My_Tie_Hash', foo => 'bar' ]  ;

      # create a hash where values are tied scalars
      tie %hash, 'Class::MakeMethods::Utility::TieHash',
        tie_storage => [ 'MyTieScalar', @my_args] ;

      # create a hash where values are autovivified objects
      tie %hash, 'Class::MakeMethods::Utility::TieHash',
        class_storage => [ 'MyClass' , @my_args ] ;

      # create a hash where values are objects (must be assigned)
      tie %hash, 'Class::MakeMethods::Utility::TieHash',
        class_storage => 'MyClass', autovivify => 0 ;


 Copyright (c) 2004 Dominique Dumont. All rights reserved.
 This program is free software; you can redistribute it and/or
 modify it under the same terms as Perl itself.


Dominique Dumont
"Delivering successful solutions requires giving people what they
need, not what they want." Kurt Bittner

Site Timeline