Subject: [ANNOUNCE] Tie::SentientHash 0.53
From: Andrew Ford <[email-masked]>
Date: 9 Aug 1999 18:13:59 GMT
Newsgroups: comp.lang.perl.announce,comp.lang.perl.modules

Version 0.53 of Tie::SentientHash has been uploaded to CPAN.  The man
page follows:

Name
       Tie::SentientHash - Perl module implementing intelligent
       objects

Synopsis
         use Tie::SentientHash;

         $hashref = new Tie::SentientHash $meta_data, $initial_data;
         $untiedhash = $hashref->export;
         $metadata   = $hashref->_metadata;

         $hashref->{key} = 'value';
         $hashref->{key1}{key2} = $value;
         $value2 = $hashref->{key};
         undef $hashref;

Description
       The Tie::SentientHash package provides intelligent
       objects.  The objects are represented as hashes which:

       *    provide read-only elements

       *    provide 'special' elements that are handled by user-
            supplied functions

       *    disallow changes to the data as specified by metadata

       *    track changes and call a 'commit changes' function
            when the object is destroyed

       References to scalars, arrays and hashes can be stored in
       hash elements in which case the referenced object is tied
       to an internal class of the appropriate type
       (Tie::SentientHash::NestedHash, ::NestedArray or
       ::NestedScalar), so that changes to the nested data
       structures can be tracked.

       The constructor is invoked with two hash references: the
       first contains metadata and the second the initial data
       values.  The metadata hash may contain the following
       flags:

       READONLY
           a list of hash entries that are read-only (read-only
           elements cannot be modified -- except by special
           element handlers -- or deleted and are not deleted
           when the CLEAR method is called)

       SPECIAL
           a hash of name/subroutine-refs pairs that specifies
           elements that are handled specially (special elements
           also cannot be deleted).  The user function is called
           both for STORE (with four arguments) and for FETCH
           (with three arguments).  The arguments are: a
           reference to the metadata hash, a reference to the
           data hash, the element key and if the funtion is being
           called for a STORE operation, the value to be stored.
           SPECIAL elements can be used to implement calculated
           attributes.

       TRACK_CHANGES
           flag to indicate that the class should keep track of
           the keys of modified (top-level) hash elements

       COMMIT_SUB
           a reference to a subroutine to commit changes (called
           with a reference to the data hash and a reference to
           the metadata hash)

       FORBID_INSERTS
           forbid inserts into hash and sub-hashes/arrays

       FORBID_DELETES
           forbid deletes from hash

       FORBID_CHANGES
           forbid any changes

       Trying to change an object in a way that is forbidden by
       the metadata will cause the module to croak.

       Changes are only tracked at the top level.

Example
       I use Tie::SentientHash as the basis for implementing
       persistent objects in my CGI/mod_perl scripts.  The
       details of reading and writing the objects from and to the
       database is handled by a class, but neither the class nor
       the high level code needs to keep track of whether the
       object has been changed in any way.

       For example if you had a pay per view system of some kind
       you could have a script that contained the following
       fragment:

          sub pay_per_view ($$) {
            my($cust_id, $cost) = @_;

            my $cust = load Customer $cust_id;
            $cust->{CREDIT} -= $cost;
          }

       The customer object would be implemented in a module
       sketched out below.  A commit function is specified on the
       call to create a new sentient object, and that function
       will be called when $cust goes out of scope at the end of
       the pay_per_view function and can write the modified
       object back to the database.  If none of the attributes
       had been modified then the commit function would not be
       invoked.

          package Customer;

          sub load ($$) {
            my ($class, $cust_id) = @_;
            my $data = {};

            # read customer data from a database into $data

            my $meta = { COMMIT_SUB     => \&_commit,
                         READONLY       => [ qw( CUST_ID ) ],
                         FORBID_INSERTS => 1 };

            return bless new Tie::SentientHash($meta, $data), $class;
          }

          sub _commit ($$) {
            my ($meta, $data) = @_;

            # As we have been called, something has changed.  The names of
            # the modified fields are the keys of $meta->{MODIFIED}.  We had
            # better write the data back out to the database.

          }

Restrictions
       Full array semantics are only supported for Perl version
       5.005.

Author
       Andrew Ford <[email-masked]>

See Also
       perl(1).

Copyright
       Copyright 1999 Ford & Mason Ltd. All rights reserved.

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

-- 
Andrew Ford,  Director       Ford & Mason Ltd           +44 1531 829900 (tel)
[email-masked]      South Wing, Compton House  +44 1531 829901 (fax)
http://www.ford-mason.co.uk  Compton Green, Redmarley   +44 385 258278 (mobile)
http://www.refcards.com      Gloucester, GL19 3JB, UK