# NAME

Hash::Compact - A hash-based object implementation with key alias and
default value support

# SYNOPSIS

 package My::Memcached;

 use strict;
 use warnings;
 use parent qw(Cache::Memcached::Fast);

 use JSON;
 use Hash::Compact;

 my $OPTIONS = {
     foo => {
         alias_for => 'f',
     },
     bar => {
         alias_for => 'b',
         default   => 'bar',
     },
 };

 sub get {
     my ($self, $key) = @_;
     my $value = $self->SUPER::get($key);
     Hash::Compact->new(decode_json $value, $OPTIONS);
 }

 sub set {
     my ($self, $key, $value, $expire) = @_;
     my $hash = Hash::Compact->new($value, $OPTIONS);
     $self->SUPER::set($key, encode_json $hash->compact, $expire);
 }

 package main;

 use strict;
 use warnings;
 use Test::More;

 my $key   = 'key';
 my $value = { foo => 'foo' };
 my $memd  = My::Memcached->new({servers => [qw(localhost:11211)]});
    $memd->set($key, $value);

 my $cached_value = $memd->get($key);
 is        $cached_value->param('foo'), 'foo';
 is        $cached_value->param('bar'), 'bar';
 is_deeply $cached_value->compact, +{ f => 'foo' };

 $cached_value->param(bar => 'baz');
 $memd->set($key, $cached_value->compact);

 $cached_value = $memd->get($key);
 is        $cached_value->param('foo'), 'foo';
 is        $cached_value->param('bar'), 'baz';
 is_deeply $cached_value->compact, +{ f => 'foo', b => 'baz' };

 done_testing;

# DESCRIPTION

When we store some structured value into a column of a relational
database or some key/value storage, redundancy of long key names can
be a problem for storage space.

This module is yet another hash-based object implementation which aims
to be aware of both space efficiency and easiness to use for us.

# METHODS

## new (I<\%hash> I<[, \%options]>)

 my $hash = Hash::Compact->new({
         foo => 'foo',
     }, {
         foo => {
             alias_for => 'f',
         },
         bar => {
             alias_for => 'b',
             default   => 'bar',
         },
     },
 );

Creates and returns a new Hash::Compact object. If `\%options` not
passed, Hash::Compact object `$hash` will be just a plain hash-based
object.

`\%options` is a hash-ref which key/value pairs are associated with
ones of `\%hash`. It may contain the fields below:

- * alias_for

Alias to an actual key. If it's passed, `\%hash` will be compacted
into another hash which has aliased key. The original key of `\%hash`
will be just an alias to an actual key.

- * default

If this exists and the value associated with the key of `\%hash` is
undefined, Hash::Compact object `$hash` returns just the value. It's
for space efficiency; `$hash` doesn't need to have key/value pair
when the value isn't defined or it's same as default value.

## param (I<$key>)

## param (I<%pairs>)

 $hash->param('foo');          #=> 'foo'
 $hash->param('bar');          #=> 'bar' (returns the default value)

 $hash->param(
     bar => 'baz',
     qux => 'quux',
 );
 $hash->param('bar');          #=> 'baz'

Setter/getter method.

## compact ()

 my $compact_hash_ref = $hash->compact;
 #=> { f => 'foo', b => 'baz' qux => 'quux' } (returns a compacted hash)

Returns a compacted hash according to `\%options` passed into the
constructor above;

## to_hash ()

This method will be deprecated and removed at later version.

## keys ()

 @keys = $hash->keys; #=> (foo, bar, qux)

Returns the original key names. If `default` option is set for a key,
the key will be returned even if the value associated with the key is
not set.

## original ()

 my $original_hash_ref = $hash->original;
 #=> { foo => 'foo', bar => 'baz' qux => 'quux' } (returns an original hash)

Returns the original key-value pairs as HashRef, which includes
key-value pairs if the key-values not set but `default` option is
designated.

# AUTHOR

Kentaro Kuribayashi <[email protected]>

# SEE ALSO

# LICENSE

Copyright (C) Kentaro Kuribayashi

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