Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Hash::AsObject(3)     User Contributed Perl Documentation    Hash::AsObject(3)

       Hash::AsObject -	treat hashes as	objects, with arbitrary

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

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

       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.

       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.

	       $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

	       $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'.

	       $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.

	       $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.

	   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';

	   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'.

       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";
	   print ref($foo), "\n";

       Produces	the following output:


       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:


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

	   my $foo = { 'bar' =>	123 };
	   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.

       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.

       o   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});

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

       o   Define multiple classes in "Hash/"?  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...


       Paul Hoffman <nkuitse AT	cpan DOT org>

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

	   [% %]

       Made me yearn to	write Perl code	like this:


       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.24.1			  2009-12-09		     Hash::AsObject(3)


Want to link to this manual page? Use this URL:

home | help