---
name: "Hash::AsObject"
section: "3pm"
platform: "linux"
package: "libhash-asobject-perl"
version: "0.13-4"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Hash::AsObject"
---

# Hash::AsObject(3pm)

treat hashes as objects, with arbitrary accessors/mutators

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