# NAME

Catalyst::Model::DataHash - Expose Perl::Data::Collection::Hash as a Per Request Model

# SYNOPSIS

Create a Model Subclass:

    package MyApp::Model::Foo;

    use Moose;
    extends 'Catalyst::Model::DataHash';

    __PACKAGE__->meta->make_immutable;

Use it in a controller:

    sub myaction :Local {
      my ($self, $c) = @_;

      # Default API
      $c->model('DataHash')->set(a=>1, b=>2);
      $c->model('DataHash')->get('a'); # 1
      $c->model('DataHash')->get('b'); # 2

      # Alternative accessors
      $c->model('DataHash')->a; # 1

      # RAISES AN EXCEPTION
      $c->model('DataHash')->not_yet_set;
      $c->model('DataHash')->set(a=>'already set...');
    }

You might find it useful to make this your default model:

    MyApp->config(default_model=>'DataHash');

So that you can use this without naming the model:

    sub myaction :Local {
      my ($self, $c) = @_;
      $c->model->set(a=>1, b=>2);
      $c->model->get('a'); # 1
      $c->model->get('b'); # 2

      #alternative accessors
      $c->model->a; # 1
    }

Which makes it less verbose.  Alternatively you can use the included plugin
[Catalyst::Plugin::DataHash](https://metacpan.org/pod/Catalyst::Plugin::DataHash) which injects a DataHash model for you into your
application, and sets it to be the default model:

    package MyApp;

    use Catalyst qw/DataHash/;

    MyApp->setup;

Then you can just do (in an action):

    sub myaction :Local {
      my ($self, $c) = @_;
      $c->model->set(a=>1);
    }

# DESCRIPTION

The most common way that a controller shares information between actions and the
view is to set key / values in the stash:

    $c->stash(a=>1, b=>2);

The stash suffers from several downsides, some of which include the fact it is
a global hash and is prone to typos and related confusion, like how it can auto-vivify
a stash key when a value does not already exist.  This [Catalyst](https://metacpan.org/pod/Catalyst)
model offers an approach to providing stash-like features with a slightly less
error prone interface.  It is also hoped that it might inspire you to think about
how to better use models in your [Catalyst](https://metacpan.org/pod/Catalyst) application to properly type your
interfaces.  It wraps [Perl::Data](https://metacpan.org/pod/Perl::Data), specifically [Data::Perl::Collection::Hash](https://metacpan.org/pod/Data::Perl::Collection::Hash)
and addes a bit of error checking and a method it ease integration with JSON encoders.

This is a 'per-request' Catalyst model, which means that each new request can get one
model for use during the request duration.

# METHODS

This model provides the following methods, most of which are delegated to 
[Data::Perl::Collection::Hash](https://metacpan.org/pod/Data::Perl::Collection::Hash). Most of this documention following is copied verbosely
from that distribution.  When we'd adapted functionality, this is noted.

## set($key => $value, $key2 => $value2...)

Sets the elements in the hash to the given values. It returns the new values set for each
key, in the same order as the keys passed to the method.

This method requires at least two arguments, and expects an even number of arguments.

**Added Behavior**: If you try to set a key that already exists, this will raise an exception.

## get($key1, $key2, ...)

Returns a list of values in the hash for the given keys.

This method requires at least one argument.

**Added Behavior**: If you try to get a key that has not already been set, this will raise an
exception.

## keys

Returns the list of keys in the hash.

This method does not accept any arguments.

## delete($key, $key2, $key3...)
Removes the elements with the given keys.

Returns a list of values in the hash for the deleted keys.

**Added Behavior**: If you try to delete a key that has not already been set, this will raise an
exception.

## exists($key)

Returns true if the given key is present in the hash.

This method requires a single argument.

## defined($key)

Returns true if the value of a given key is defined.

This method requires a single argument.

## values

Returns the list of values in the hash.

This method does not accept any arguments.

## kv

Returns the key/value pairs in the hash as an array of array references.

    for my $pair ( $object->option_pairs ) {
        print "$pair->[0] = $pair->[1]\n";
    }

This method does not accept any arguments.

## elements/all

Returns the key/value pairs in the hash as a flattened list..

This method does not accept any arguments.

## clear

Resets the hash to an empty value, like %hash = ().

This method does not accept any arguments.

## count

Returns the number of elements in the hash.

This method does not accept any arguments.

## accessor($key)

## accessor($key, $value)

If passed one argument, returns the value of the specified key. 
If passed two arguments, sets the value of the specified key.

**Added Behavior**: If you try to get a key that has not already been set, this will raise an
exception.  If you try to set a key that has already been set, it will raise an exception.

## shallow\_clone
This method returns a shallow clone of the hash reference. The return value is a 
reference to a new hash with the same keys and values. It is shallow because any values
that were references in the original will be the same references in the clone.

## TO\_JSON

Returns a hashref of all the existing data suitable to send to a JSON serializer.

# SEE ALSO

[Catalyst](https://metacpan.org/pod/Catalyst), [Data::Perl](https://metacpan.org/pod/Data::Perl).

# AUTHOR

John Napiorkowski [email:jjnapiork@cpan.org](email:jjnapiork@cpan.org)

# COPYRIGHT & LICENSE

Copyright 2015, John Napiorkowski [email:jjnapiork@cpan.org](email:jjnapiork@cpan.org)

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