|
NAMEHash::AutoHash - Object-oriented access to real and tied hashesVERSIONVersion 1.17SYNOPSISuse Hash::AutoHash; # real hash my $autohash=new Hash::AutoHash name=>'Joe', hobbies=>['hiking','cooking']; # access or change hash elements via methods my $name=$autohash->name; # 'Joe' my $hobbies=$autohash->hobbies; # ['hiking','cooking'] $autohash->hobbies(['go','chess']); # hobbies now ['go','chess'] # you can also use standard hash notation and functions my($name,$hobbies)=@$autohash{qw(name hobbies)}; $autohash->{name}='Moe'; # name now 'Moe' my @values=values %$autohash; # ('Moe',['go','chess']) # tied hash. use Hash::AutoHash qw(autohash_tie); use Tie::Hash::MultiValue; # from CPAN. each hash element is ARRAY my $autohash=autohash_tie Tie::Hash::MultiValue; $autohash->name('Joe'); $autohash->hobbies('hiking','cooking'); my $name=$autohash->name; # ['Joe'] my $hobbies=$autohash->hobbies; # ['hiking','cooking'] # real hash via constructor function. analogous to autohash_tied use Hash::AutoHash qw(autohash_hash); my $autohash=autohash_hash name=>'Joe',hobbies=>['hiking','cooking']; my $name=$autohash->name; # 'Joe' my $hobbies=$autohash->hobbies; # ['hiking','cooking'] # autohash_set is easy way to set multiple elements at once # it has two forms autohash_set($autohash,name=>'Moe',hobbies=>['go','chess']); autohash_set($autohash,['name','hobbies'],['Moe',['go','chess']]); # alias $autohash to regular hash for more concise hash notation use Hash::AutoHash qw(autohash_alias); my %hash; autohash_alias($autohash,%hash); # access or change hash elements without using -> $hash{name}='Joe'; # changes $autohash and %hash my $name_via_hash=$hash{name}; # 'Joe' my $name_via_autohash=$autohash->name; # 'Joe' # get two elements in one statement my($name,$hobbies)=@hash{qw(name hobbies)}; # nested structures work, too, of course my $name=autohash_hash first=>'Joe',last=>'Doe'; my $person=autohash_hash name=>$name,hobbies=>['hiking','cooking']; my $first=$person->name->first; # 'Joe' DESCRIPTIONThis is yet another module that lets you access or change the elements of a hash using methods with the same name as the element's key. It follows in the footsteps of Hash::AsObject, Hash::Inflator, Data::OpenStruct::Deep, Object::AutoAccessor, and probably others. The main difference between this module and its forebears is that it supports tied hashes, in addition to regular hashes. This allows a modular division of labor: this class is generic and treats all hashes the same; any special semantics come from the tied hash.The class has a 'new' method but also supplies several functions for constructing new Hash::AutoHash objects. The constructor functions shown in the SYNOPSIS are all you need for typical uses. autohash_hash creates a new 'real' (ie, not tied) Hash::AutoHash object; autohash_tie creates a new tied Hash::AutoHash object. Once the objects are constructed, the class treats them the same way. You can get the value of a hash element using hash notation or by invoking a method with the same name as the key. For example, the following are equivalent. my $name=$autohash->{name}; my $name=$autohash->name; You can also change the value of an element using either notation: $autohash->{name}='Jonathan'; $autohash->name('Jonathan'); And you can add new elements using either notation: $autohash->{first_name}='Joe'; $autohash->last_name('Plumber'); CAUTIONS
Nested structures work straightforwardly. If a value is a Hash::AutoHash object, you can use a series of '->' operators to get to its elements. my $name=autohash_hash first=>'Joe',last=>'Doe'; my $person=autohash_hash name=>$name,hobbies=>['hiking','cooking']; my $first=$person->name->first; # $name is 'Joe' The class provides a full plate of functions for performing hash operations on Hash::AutoHash objects. These are useful if you want to avoid hash notation all together. The following example uses these functions to removes hash elements whose values are undefined: use Hash::AutoHash qw(autohash_keys autohash_delete); my @keys=autohash_keys($autohash); for my $key (@keys) { autohash_delete($autohash,$key) unless defined $autohash->$key; } The autohash_set function is an easy way to set multiple elements at once. This is especially handy for setting the initial value of a tied Hash::AutoHash object, in cases where the tied hash cannot do this directly. use Hash::AutoHash qw(autohash_set); my $autohash=autohash_tie Tie::Hash::MultiValue; autohash_set($autohash,name=>'Joe',hobbies=>'hiking',hobbies=>'cooking'); In the example above, 'hobbies' is set twice, because that's how Tie::Hash::MultiValue lets you set a multi-valued element. Setting the element to an ARRAY of values doesn't do it. You can also feed autohash_set separate ARRAYs of keys and values. my $autohash=autohash_tie Tie::Hash::MultiValue; autohash_set($autohash,['name','hobbies'],['Joe','hiking']); You can alias the object to a regular hash for more concise hash notation. use Hash::AutoHash qw(autohash_alias); my $autohash=autohash_tie Tie::Hash::MultiValue; autohash_alias($autohash,%hash); $hash{name}='Joe'; # changes both $autohash and %hash $autohash->hobbies('kayaking'); # changes both $autohash and %hash my($name,$hobbies)=@hash{qw(name hobbies)}; By aliasing $autohash to %hash, you avoid the need to dereference the variable when using hash notation. Admittedly, this is a minor convenience, but the reduction in verbosity can be useful in some cases. It is also possible to link a Hash::AutoHash object to an existing hash which may be real or tied, a process we call wrapping. The effect is similar to aliasing. The difference is that with aliasing, the object exists first whereas with wrapping, the hash exists first. # wrap existing hash - can be real or tied. use Hash::AutoHash qw(autohash_wrap); my %hash=(name=>'Moe',hobbies=>['running','rowing']); my $autohash=autohash_wrap %hash; my($name,$hobbies)=@hash{qw(name hobbies)}; $hash{name}='Joe'; # changes both $autohash and %hash $autohash->hobbies('kayaking'); # changes both $autohash and %hash If the Hash::AutoHash object is tied, the autohash_tied function returns the object implementing the tied hash. If the Hash::AutoHash object is aliased to a hash, the function also works on the hash. autohash_tied is almost equivalent to Perl's built-in tied function; see "Accessing the tied object" for details. use Hash::AutoHash qw(autohash_tied); my $autohash=autohash_tie Tie::Hash::MultiValue; my $tied=autohash_tied($autohash); # Tie::Hash::MultiValue object autohash_alias($autohash,%hash); my $tied=autohash_tied(%hash); # same object as above If you're certain the Hash::AutoHash object is tied, you can invoke methods on the tied object as follows. CAUTION: this will generate an error if the object is not tied. my $result=autohash_tied($autohash)->some_method(@parameters); A safer way is to supply the method name and parameters as additional arguments to the autohash_tied function. This will return undef if the object is not tied. my $result=autohash_tied($autohash,'some_method',@parameters); Keeping the namespace cleanHash::AutoHash provides all of its capabilities through class methods (these are methods, such as 'new', that are invoked on the class rather than on individual objects) or through functions that must be imported into the caller's namespace. In most cases, a method invoked on an object is interpreted as a request to access or change an element of the underlying hash.CAUTION: As of version 1.14, it is not possible to use method notation for keys with the same names as methods inherited from UNIVERSAL (the base class of everything). These are 'can', 'isa', 'DOES', and 'VERSION'. The reason is that as of Perl 5.9.3, calling UNIVERSAL methods as functions is deprecated and developers are encouraged to use method form instead. Previous versions of AutoHash are incompatible with CPAN modules that adopt this style. Special care is needed with methods used implicitly by Perl to implement common features ('import', 'AUTOLOAD', 'DESTROY'). 'import' is usually invoked by Perl as a class method when processing 'use' statements to import functions into the caller's namespace. We preserve this behavior but when invoked on an object, we interpret the call as a request to access or change the element of the underlying hash whose kye is 'import'. 'AUTOLOAD' and 'DESTROY' pose different problems, since they are logically object methods. Fortunately, Perl leaves enough clues to let us tell whether these methods were called by Perl or directly by the application. When called by Perl, they operate as Perl expects; when called by the application, they access the underlying hash. The 'new' method warrants special mention. In normal use, 'new' is almost always invoked as a class method, eg, new Hash::AutoHash(name=>'Joe') This invokes the 'new' method on Hash::AutoHash which constructs a new object as expected. If, however, 'new' is invoked on an object, eg, $autohash->new the code accesses the hash element named 'new'. ConstructorsHash::AutoHash provides a number of constructor functions as well as a 'new' method which is simply a front-end for the constructor functions. To use the constructor functions, you must import them into the caller's namespace using the common Perl idiom of listing the desired functions in a 'use' statement.use Hash::AutoHash qw(autohash_hash autohash_tie autohash_wrap autohash_wrapobj autohash_wraptie autohash_new); autohash_hash Title : autohash_hash Usage : $autohash=autohash_hash name=>'Joe',hobbies=>['hiking','cooking'] Function: Create a real (ie, not tied) Hash::AutoHash object and optionally set its initial value Returns : Hash::AutoHash object Args : Optional list of key=>value pairs autohash_tie Title : autohash_tie Usage : $autohash=autohash_tie Tie::Hash::MultiValue Function: Create a tied Hash::AutoHash object Returns : Hash::AutoHash object tied to the given class Args : The class implementing the tied hash; quotes are optional. Any additional parameters are passed to the TIEHASH constructor. The object returned by autohash_tie is simultaneously a Hash::AutoHash object and a tied hash. To get the object implementing the tied hash (ie, the object returned by Perl's tie function), do either of the following. my $tied=tied %$autohash; # note '%' before '$' my $tied=autohash_tied($autohash); # note no '%' before '$' The autohash_set function is a convenient way to set the initial value of a tied Hash::AutoHash object in cases where the tied hash cannot do this directly. use Hash::AutoHash qw(autohash_set); my $autohash=autohash_tie Tie::Hash::MultiValue; autohash_set ($autohash,name=>'Joe',hobbies=>'hiking',hobbies=>'cooking'); In the example above, 'hobbies' is set twice, because that's how Tie::Hash::MultiValue lets you set a multi-valued element. Setting the element to an ARRAY of values doesn't do it. You can also provide autohash_set with separate ARRAYs of keys and values. my $autohash=autohash_tie Tie::Hash::MultiValue; autohash_set($autohash,['name','hobbies'],['Joe','hiking']); Wrapping an existing hash or tied object The constructor functions described in this section let you create a Hash::AutoHash object that is linked to an existing hash or tied object, a process we call wrapping. Once the linkage is made, the contents of the object and hash will be identical; any changes made to one will be reflected in the other. autohash_wrap Title : autohash_wrap Usage : $autohash=autohash_wrap %hash,name=>'Joe',hobbies=>['hiking','cooking'] Function: Create a Hash::AutoHash object linked to the hash. The initial value of the object is whatever value the hash currently has. Any additional parameters are key=>value pairs which are used to set further elements of the object (and hash) Returns : Hash::AutoHash object linked to the hash Args : Hash and optional list of key=>value pairs. The hash can be real or tied. The key=>value pairs set further elements of the object (and hash). Notes : If the hash is tied, the constructed object will be tied to the object implementing the tied hash. If the hash is not tied, the constructed object will be tied to an object of type Hash::AutoHash::dup which implements the linking. autohash_wrapobj Title : autohash_wrapobj Usage : $autohash=autohash_wrapobj $tied_object,name=>'Joe',hobbies=>'hiking' Function: Create a Hash::AutoHash object linked to a tied hash given the object implementing the tie (in other words, the object returned by Perl's tie function). The initial value of the constructed object is whatever value the hash currently has. Any additional parameters are key=>value pairs which are used to set further elements of the object (and hash). Returns : Hash::AutoHash object linked to the hash Args : Object implementing a tied hash and optional list of key=>value pairs. The key=>value pairs set further elements of the object (and hash). Here is another, perhaps more typical, illustration of autohash_wrapobj. $autohash=autohash_wrapobj tie %hash,'Tie::Hash::MultiValue' You can set initial values in the constructed object by including them as parameters to the function, using parentheses to keep them separate from the parameters to 'tie'. All the parentheses in the example below are necessary. $autohash=autohash_wrapobj ((tie %hash,'Tie::Hash::MultiValue'), name=>'Joe',hobbies=>'hiking',hobbies=>'cooking') autohash_wraptie Title : autohash_wraptie Usage : $autohash=autohash_wraptie %hash,Tie::Hash::MultiValue Function: Create a Hash::AutoHash object linked to a tied hash and do the tying in one step. Returns : Hash::AutoHash object linked to the hash. As a side effect, the hash will be tied to the given class. Args : Hash and the class implementing the tied hash (quotes are optional). Any additional parameters are passed to the TIEHASH constructor. Notes : This is equivalent to $autohash=autohash_wrapobj tie %hash,'Tie::Hash::MultiValue' new 'new' and autohash_new are front-ends to the other constructor functions. To accommodate the diversity of the other functions, the parameter syntax makes some assumptions and is not completely general. Title : new Usage : $autohash=new Hash::AutoHash name=>'Joe',hobbies=>['hiking','cooking'] -- OR -- $autohash=new Hash::AutoHash ['Tie::Hash::MultiValue'], name=>'Joe',hobbies=>'hiking',hobbies=>'cooking' -- OR -- $autohash=new Hash::AutoHash \%hash, name=>'Joe',hobbies=>'hiking',hobbies=>'cooking' -- OR -- $autohash=new Hash::AutoHash $tied_object, name=>'Joe',hobbies=>'hiking',hobbies=>'cooking' -- OR -- $autohash=new Hash::AutoHash [\%hash,'Tie::Hash::MultiValue'], name=>'Joe',hobbies=>'hiking',hobbies=>'cooking' Function: Create a Hash::AutoHash object and optionally set elements. Form 1, like autohash_hash, creates a real (ie, not tied) object. Form 2, like autohash_tie, creates a tied object, Form 3, like autohash_wrap, creates an object linked to a hash. Form 4, like autohash_wrapobj, creates an object linked to a tied hash given the object implementing the tie Form 5, like autohash_wraptie, creates an object linked to a tied hash and does the tie in one step Returns : Hash::AutoHash object Args : The first argument determines the form. The remaining arguments are an optional list of key=>value pairs which are used to set elements of the object Form 1. first argument is a scalar (eg, a string) Form 2. first argument is an ARRAY whose elements are the class implementing the tied hash (quotes are required) followed by additional parameters for the the TIEHASH constructor. Form 3. first argument is a HASH that doesn't look like a tied object. See form 4. Form 4. first argument is a HASH that looks like a tied object; this is any blessed HASH that provides a TIEHASH method. Form 5. first argument is an ARRAY whose elements are a HASH and the class implementing the tied hash (quotes are required) followed by additional parameters for the the TIEHASH constructor. autohash_new Like new, autohash_new is a front-end to the other constructor functions. We provide it for stylistic consistency. To accommodate the diversity of the other functions, the parameter syntax makes some assumptions and is not completely general. Title : autohash_new Usage : $autohash=autohash_new name=>'Joe',hobbies=>['hiking','cooking'] -- OR -- $autohash=autohash_new ['Tie::Hash::MultiValue'], name=>'Joe',hobbies=>'hiking',hobbies=>'cooking' -- OR -- $autohash=autohash_new \%hash, name=>'Joe',hobbies=>'hiking',hobbies=>'cooking' -- OR -- $autohash=autohash_new $tied_object, name=>'Joe',hobbies=>'hiking',hobbies=>'cooking' -- OR -- $autohash=autohash_new [\%hash,'Tie::Hash::MultiValue'], name=>'Joe',hobbies=>'hiking',hobbies=>'cooking' Function: same as 'new' Returns : Hash::AutoHash object Args : same as 'new' Aliasing: autohash_aliasYou can alias a Hash::AutoHash object to a regular hash to avoid the need to dereference the variable when using hash notation. The effect is similar to wrapping an existing hash via the autohash_wrap function. The difference is that with aliasing, the Hash::AutoHash object exists first and you are linking a hash to it, whereas with wrapping, the hash exists first.Once the linkage is made, the contents of the object and hash will be identical; any changes made to one will be reflected in the other. As a convenience, the autoahash_alias functions can link in either direction depending on whether the given object exists. Title : autohash_alias Usage : autohash_alias($autohash,%hash) Function: If $autohash is defined and is a Hash::AutoHash object, link $autohash to %hash. If $autohash is not defined, create a new Hash::AutoHash object that wraps %hash Args : Hash::AutoHash object or undef and hash Returns : Hash::AutoHash object Getting and setting hash elementsOne way to get and set hash elements is to treat the object as a HASH and use standard hash notation, eg,my $autohash=autohash_hash name=>'Joe',hobbies=>['hiking','cooking']; my $name=$autohash->{name}; my($name,$hobbies)=@$autohash{qw(name hobbies)}; $autohash->{name}='Moe'; @$autohash{qw(name hobbies)}=('Joe',['running','rowing']); A second approach is to invoke a method with the name of the key. Eg, $autohash->name; $autohash->name('Moe'); # sets name to 'Moe' $autohash->hobbies(['blading','rowing']); # sets hobbies to ['blading','rowing'] New hash elements can be added using either notation. For example, $autohash->{first_name}='Joe'; $autohash->last_name('Plumber'); If the object wraps or aliases a hash, you can operate on the hash instead of the Hash::AutoHash object. This may allow more concise notation by avoiding the need to dereference the object repeatedly. use Hash::AutoHash qw(autohash_alias); autohash_alias($autohash,%hash); my $name=$hash{name}; # instead of $autohash->{name} my @keys=keys %hash; # instead of keys %$autohash The class also provides two functions for wholesale manipulation of arguments. To use these functions, you must import them into the caller's namespace using the common Perl idiom of listing the desired functions in a 'use' statement. use Hash::AutoHash qw(autohash_get autohash_set); autohash_get Title : autohash_get Usage : ($name,$hobbies)=autohash_get($autohash,qw(name hobbies)) Function: Get values for multiple keys. Args : Hash::AutoHash object and list of keys Returns : list of argument values autohash_set Title : autohash_set Usage : autohash_set($autohash,name=>'Joe Plumber',first_name=>'Joe') -- OR -- autohash_set($autohash,['name','first_name'],['Joe Plumber','Joe']) Function: Set multiple arguments in existing object. Args : Form 1. Hash::AutoHash object and list of key=>value pairs Form 2. Hash::AutoHash object, ARRAY of keys, ARRAY of values Returns : Hash::AutoHash object Functions for hash-like operationsThese functions provide hash-like operations on Hash::AutoHash objects. These are useful if you want to avoid hash notation all together. To use these functions, you must import them into the caller's namespace using the common Perl idiom of listing the desired functions in a 'use' statement.use Hash::AutoHash qw(autohash_clear autohash_delete autohash_each autohash_exists autohash_keys autohash_values autohash_count autohash_empty autohash_notempty); autohash_clear Title : autohash_clear Usage : autohash_clear($autohash) Function: Delete entire contents of $autohash Args : Hash::AutoHash object Returns : nothing autohash_delete Title : autohash_delete Usage : autohash_delete($autohash,@keys) Function: Delete keys and their values from $autohash. Args : Hash::AutoHash object, list of keys Returns : nothing autohash_exists Title : autohash_exists Usage : if (autohash_exists($autohash,$key)) { ... } Function: Test whether key is present in $autohash. Args : Hash::AutoHash object, key Returns : boolean autohash_each Title : autohash_each Usage : while (my($key,$value)=autohash_each($autohash)) { ... } -- OR -- while (my $key=autohash_each($autohash)) { ... } Function: Iterate over all key=>value pairs or all keys present in $autohash Args : Hash::AutoHash object Returns : list context: next key=>value pair in $autohash or empty list at end scalar context: next key in $autohash or undef at end autohash_keys Title : autohash_keys Usage : @keys=autohash_keys($autohash) Function: Get all keys that are present in $autohash Args : Hash::AutoHash object Returns : list of keys autohash_values Title : autohash_values Usage : @values=autohash_values($autohash) Function: Get the values of all keys that are present in $autohash Args : Hash::AutoHash object Returns : list of values autohash_count Title : autohash_count Usage : $count=autohash_count($autohash) Function: Get the number keys that are present in $autohash Args : Hash::AutoHash object Returns : number autohash_empty Title : autohash_empty Usage : if (autohash_empty($autohash)) { ... } Function: Test whether $autohash is empty Args : Hash::AutoHash object Returns : boolean autohash_notempty Title : autohash_notempty Usage : if (autohash_notempty($autohash)) { ... } Function: Test whether $autohash is not empty. Complement of autohash_empty Args : Hash::AutoHash object Returns : boolean Accessing the tied object: autohash_tiedIf a Hash::AutoHash object is tied, the application sometimes needs to access the object implementing the underlying tied hash. The term 'tied object' refers to this object. This is necessary, for example, if the tied object provides options that affect the operation of the tied hash.In many cases, you can access the tied object using Perl's built-in tied function. my $autohash=autohash_tie Tie::Hash::MultiValue; my $tied=tied %$autohash; # note leading '%' However Perl's built-in tied function doesn't do the right thing when the Hash::AutoHash object wraps or is aliased to a regular (not tied) hash. In these cases, the code uses an internal tied hash to implement the connection between the Hash::AutoHash object and the hash. (The internal tied hash is currently named Hash::AutoHash::alias, but this is subject to change). The autohash_tied function is a safer way to get the tied object. In most cases, it is equivalent to Perl's built-in tied function, but it reaches through the internal Hash::AutoHash::alias object when one is present. If the Hash::AutoHash object is aliased to a hash, the function also works on the hash. use Hash::AutoHash qw(autohash_tied); my $autohash=autohash_tie Tie::Hash::MultiValue; my $tied=autohash_tied($autohash); # Tie::Hash::MultiValue object autohash_alias($autohash,%hash); my $tied=autohash_tied(%hash); # same object as above If you're certain the Hash::AutoHash object is tied, you can invoke methods on the result of autohash_tied. This will generate an error if the object is not tied. A safer way is to supply the method name and parameters as additional arguments to the autohash_tied function. This will return undef if the object is not tied. # two ways to invoke method on tied object # 1st generates error if $autohash not tied # 2nd returns undef if $autohash not tied my $result=autohash_tied($autohash)->some_method(@parameters); my $result=autohash_tied($autohash,'some_method',@parameters); use Hash::AutoHash qw(autohash_tied); Title : autohash_tied Usage : $tied=autohash_tied($autohash) -- OR -- $tied=autohash_tied(%hash) -- OR -- $result=autohash_tied($autohash,'some_method',@parameters) -- OR -- $result=autohash_tied(%hash,'some_method',@parameters) Function: The first two forms return the object implementing the tied hash that underlies a Hash::AutoHash object if it is tied, or undef if it isn't tied. The latter two forms invoke a method on the tied object if the Hash::AutoHash object is tied, or undef if it isn't tied. In forms 1 and 3, the first argument is the Hash::AutoHash object. In forms 2 and 4, the first argument is a hash to which a Hash::AutoHash object has been aliased Returns : In forms 1 and 2, object implementing tied hash or undef. In forms 3 and 4, result of invoking method (which can be anything or nothing), or undef. Args : Form 1. Hash::AutoHash object Form 2. hash to which Hash::AutoHash object is aliased Form 3. Hash::AutoHash object, method name, optional list of parameters for method Form 4. hash to which Hash::AutoHash object is aliased, method name, optional list of parameters for method SubclassingSpecial considerations apply when subclassing Hash::AutoHash due to its goal of keeping the namespace clean and its heavy use of functions instead of methods.A common use-case is a subclass that provides an object interface to a specific tied hash class. In such cases, the subclass would probably provide a 'new' method that constructs objects tied to that class and would probably want to hide the other constructor functions. The subclass might also want to provide the other functions from Hash::AutoHash (why not?) but might want to change their names to be consistent with the subclass's name. Here is an example subclass, TypicalChild, illustrating this use-case. TypicalChild provides a 'new' method that creates objects tied to Tie::Hash::MultiValue. The 'new' method can also set the object's initial value (the TIEHASH method of Tie::Hash::MultiValue does not support this directly). The subclass provides the other functions from Hash::AutoHash but renames each from autohash_XXX to typicalchild_XXX. package TypicalChild; use Hash::AutoHash; our @ISA=qw(Hash::AutoHash); our @NORMAL_EXPORT_OK=(); our %RENAME_EXPORT_OK=(); our @RENAME_EXPORT_OK=sub {s/^autohash/typicalchild/; $_}; our @EXPORT_OK=TypicalChild::helper->EXPORT_OK; our @SUBCLASS_EXPORT_OK=TypicalChild::helper->SUBCLASS_EXPORT_OK; ############################################################# # helper package to avoid polluting TypicalChild namespace ############################################################# package TypicalChild::helper; use Hash::AutoHash qw(autohash_tie autohash_set); use Tie::Hash::MultiValue; BEGIN { our @ISA=qw(Hash::AutoHash::helper); } sub _new { my($helper_class,$class,@args)=@_; my $self=autohash_tie Tie::Hash::MultiValue; autohash_set($self,@args); bless $self,$class; } 1; The subclass consists of two packages: TypicalChild and TypicalChild::helper. The helper package is where all the real code goes to avoid polluting TypicalChild's namespace. TypicalChild must be a subclass of Hash::AutoHash (ie, Hash::AutoHash must be in its @ISA array); TypicalChild::helper must be a subclass of Hash::AutoHash::helper (ie, Hash::AutoHash::helper must be in its @ISA array). The 'new' method of Hash::AutoHash dispatches to the '_new' method in the helper class after making sure the method was invoked on a class. That's why the code has a '_new' method in TypicalChild::helper rather than 'new' method in TypicalChild. The BEGIN block is needed to make sure @ISA is set at compile-time before @EXPORT_OK is calculated. The code in TypicalChild dealing with the various EXPORT_OK arrays handles the renaming of functions from Hash::AutoHash (or, more generally, any ancestor class), the exporting of additional functions defined by the subclass, and sets the stage for subclasses of the subclass to do the same thing. Variable: @NORMAL_EXPORT_OK Usage : @NORMAL_EXPORT_OK=qw(autohash_set typicalchild_function) Function: Functions that will be exported 'normally', in other words with no change of name. The functions can be defined here (in the helper class, not the main class!!) or in any ancestor class Variable: %NORMAL_EXPORT_OK Usage : %NORMAL_EXPORT_OK=(learn=>'autohash_set',forget=>'autohash_delete') Function: Functions that will be exported with a different name. The left-hand side of each pair is the new name; the right-hand side is the name of a function defined here (in the helper class, not the main class!!) or in any ancestor class Variable: @RENAME_EXPORT_OK Usage : @RENAME_EXPORT_OK=sub {s/^autohash/typicalchild/; $_} -- OR -- @RENAME_EXPORT_OK=(sub {s/^autohash/typicalchild/; $_}, qw(autohash_exists autohash_get)) Function: Functions that will be exported with a different name. This provides an easy way to rename many functions at once. The first element of the list is a subroutine that will be applied to each other element of the list to generate the new names. The functions in the list can be defined here (in the helper class, not the main class!!) or in any ancestor class If the list of functions is empty, the subroutine is applied to everything in its parent classes' @SUBCLASS_EXPORT_OK array. The form of the subroutine is exactly as for Perl's grep and map functions. Variable: @EXPORT_OK Usage : @EXPORT_OK=TypicalChild::helper->EXPORT_OK -- OR -- @EXPORT_OK=qw(learn forget) Function: Complete list of functions that the subclass is willing to export. The EXPORT_OK method computes this from the other variables. You can also set it explicitly. Variable: @SUBCLASS_EXPORT_OK Usage : @SUBCLASS_EXPORT_OK=TypicalChild::helper->SUBCLASS_EXPORT_OK -- OR -- @SUBCLASS_EXPORT_OK=qw(learn forget) Function: Functions that subclasses of this class might want to export. This provides the default list of functions for @RENAME_EXPORT_OK in these subclasses. The SUBCLASS_EXPORT_OK method simply sets this to @EXPORT_OK which is tantamount to assuming that subclasses may want to export everything this class exports. You can also set it explicitly. SEE ALSOperltie and Tie::Hash present background on tied hashes.Hash::AsObject, Hash::Inflator, Data::OpenStruct::Deep, and Object::AutoAccessor are similar classes and may be better choices if you don't need or want to used tied hashes. The source code of Hash::AsObject alerted us to the danger of methods inherited from UNIVERSAL. Hash::AutoHash::Args, Hash::AutoHash::MultiValued, Hash::AutoHash::AVPairsSingle, Hash::AutoHash::AVPairsMulti, Hash::AutoHash::Record are subclasses each of which provides an object interface to a specific tied hash class. Tie::Hash::MultiValue is a nice tied hash class used as an example throughout this POD. Many interesting tied hash classes are available on CPAN and can be found by searching for 'Tie::Hash'. AUTHORNat Goodman, "<natg at shore.net>"BUGS AND CAVEATSPlease report any bugs or feature requests to "bug-hash-autohash at rt.cpan.org", or through the web interface at <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Hash-AutoHash>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.Known Bugs and Caveats
SUPPORTYou can find documentation for this module with the perldoc command.perldoc Hash::AutoHash You can also look for information at:
COPYRIGHT & LICENSECopyright (c) 2008, 2009 Institute for Systems Biology (ISB). All Rights Reserved.This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See http://dev.perl.org/licenses/ for more information.
Visit the GSP FreeBSD Man Page Interface. |