dwww Home | Manual pages | Find package

Hash::AsObject(3pm)   User Contributed Perl Documentation  Hash::AsObject(3pm)

NAME
       Hash::AsObject - treat hashes as objects, with arbitrary
       accessors/mutators

SYNOPSIS
           $h = Hash::AsObject->new;
           $h->foo(123);
           print $h->foo;       # prints 123
           print $h->{'foo'};   # prints 123
           $h->{'bar'}{'baz'} = 456;
           print $h->bar->baz;  # prints 456

DESCRIPTION
       A Hash::AsObject is a blessed hash that provides read-write access to
       its elements using accessors.  (Actually, they're both accessors and
       mutators.)

       It's designed to act as much like a plain hash as possible; this means,
       for example, that you can use methods like "DESTROY" to get or set hash
       elements with that name.  See below for more information.

METHODS
       The whole point of this module is to provide arbitrary methods.  For
       the most part, these are defined at runtime by a specially written
       "AUTOLOAD" function.

       In order to behave properly in all cases, however, a number of special
       methods and functions must be supported.  Some of these are defined
       while others are simply emulated in AUTOLOAD.

       new
               $h = Hash::AsObject->new;
               $h = Hash::AsObject->new(\%some_hash);
               $h = Hash::AsObject->new(%some_other_hash);

           Create a new Hash::AsObject.

           If called as an instance method, this accesses a hash element
           'new':

               $h->{'new'} = 123;
               $h->new;       # 123
               $h->new(456);  # 456

       isa This method cannot be used to access a hash element 'isa', because
           Hash::AsObject doesn't attempt to handle it specially.

       can Similarly, this can't be used to access a hash element 'can'.

       AUTOLOAD
               $h->{'AUTOLOAD'} = 'abc';
               $h->AUTOLOAD;       # 'abc'
               $h->AUTOLOAD('xyz') # 'xyz'

           Hash::AsObject::AUTOLOAD recognizes when AUTOLOAD is begin called
           as an instance method, and treats this as an attempt to get or set
           the 'AUTOLOAD' hash element.

       DESTROY
               $h->{'DESTROY'} = [];
               $h->DESTROY;    # []
               $h->DESTROY({}) # {}

           "DESTROY" is called automatically by the Perl runtime when an
           object goes out of scope.  A Hash::AsObject can't distinguish this
           from a call to access the element $h->{'DESTROY'}, and so it
           blithely gets (or sets) the hash's 'DESTROY' element; this isn't a
           problem, since the Perl interpreter discards any value that DESTROY
           returns when called automatically.

       VERSION
           When called as a class method, this returns
           $Hash::AsObject::VERSION; when called as an instance method, it
           gets or sets the hash element 'VERSION';

       import
           Since Hash::AsObject doesn't export any symbols, this method has no
           special significance and you can safely call it as a method to get
           or set an 'import' element.

           When called as a class method, nothing happens.

       The methods "can()" and "isa()" are special, because they're defined in
       the "UNIVERSAL" class that all packages automatically inherit from.
       Unfortunately, this means that you can't use Hash::AsObject to access
       elements 'can' and 'isa'.

CAVEATS
       No distinction is made between non-existent elements and those that are
       present but undefined.  Furthermore, there's no way to delete an
       element without resorting to "delete $h->{'foo'}".

       Storing a hash directly into an element of a Hash::AsObject instance
       has the effect of blessing that hash into Hash::AsObject.

       For example, the following code:

           my $h = Hash::AsObject->new;
           my $foo = { 'bar' => 1, 'baz' => 2 };
           print ref($foo), "\n";
           $h->foo($foo);
           print ref($foo), "\n";

       Produces the following output:

           HASH
           Hash::AsObject

       I could fix this, but then code like the following would throw an
       exception, because "$h->foo($foo)" will return a plain hash reference,
       not an object:

           $h->foo($foo)->bar;

       Well, I can make "$h->foo($foo)->bar" work, but then code like this
       won't have the desired effect:

           my $foo = { 'bar' => 123 };
           $h->foo($foo);
           $h->foo->bar(456);
           print $foo->{'bar'};  # prints 123
           print $h->foo->bar;   # prints 456

       I suppose I could fix that, but that's an awful lot of work for little
       apparent benefit.

       Let me know if you have any thoughts on this.

BUGS
       Autovivification is probably not emulated correctly.

       The blessing of hashes stored in a Hash::AsObject might be considered a
       bug.  Or a feature; it depends on your point of view.

TO DO
       •   Add the capability to delete elements, perhaps like this:

               use Hash::AsObject 'deleter' => 'kill';
               $h = Hash::AsObject->new({'one' => 1, 'two' => 2});
               kill $h, 'one';

           That might seem to violate the prohibition against exporting
           functions from object-oriented packages, but then technically it
           wouldn't be exporting it from anywhere since the function would be
           constructed by hand.  Alternatively, it could work like this:

               use Hash::AsObject 'deleter' => 'kill';
               $h = Hash::AsObject->new({'one' => 1, 'two' => 2});
               $h->kill('one');

           But, again, what if the hash contained an element named 'kill'?

       •   Define multiple classes in "Hash/AsObject.pm"?  For example, there
           could be one package for read-only access to a hash, one for hashes
           that throw exceptions when accessors for non-existent keys are
           called, etc.  But this is hard to do fully without (a) altering the
           underlying hash, or (b) defining methods besides AUTOLOAD. Hmmm...

VERSION
       0.06

AUTHOR
       Paul Hoffman <nkuitse AT cpan DOT org>

CREDITS
       Andy Wardley for Template::Stash, which was my inspiration.  Writing
       template code like this:

           [% foo.bar.baz(qux) %]

       Made me yearn to write Perl code like this:

           foo->bar->baz($qux);

COPYRIGHT
       Copyright 2003-2007 Paul M. Hoffman. All rights reserved.

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

perl v5.36.0                      2022-12-12               Hash::AsObject(3pm)

Generated by dwww version 1.15 on Wed Jun 26 19:16:51 CEST 2024.