Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Hash with multiple values per key, inspired by MultiDict.py of WebOb
Perl
branch: insideout

This branch is 82 commits behind miyagawa:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib/Hash
t
xt
.gitignore
.shipit
Changes
MANIFEST
MANIFEST.SKIP
Makefile.PL
README
benchmark.pl

README

NAME
    Hash::MultiValue - Store multiple values per key

SYNOPSIS
      use Hash::MultiValue;

      my $hash = Hash::MultiValue->new(
          foo => 'a',
          foo => 'b',
          bar => 'baz',
      );

      # $hash is an object, but can be used as a hashref and DWIMs!

      my $foo = $hash->{foo};         # 'b' (the last entry)
      my $foo = $hash->get('foo');    # 'b' (always, regardless of context)
      my @foo = $hash->get_all('foo'); # ('a', 'b')

      keys %$hash; # ('foo', 'bar') not guaranteed to be ordered
      $hash->keys; # ('foo', 'bar') guaranteed to be ordered

      # get a plain hash where values may or may not be an array ref
      %hash = $hash->as_hash;

      # get a pair so you can pass it to new()
      @pairs = $hash->flatten; # ('foo' => 'a', 'foo' => 'b', 'bar' => 'baz')

DESCRIPTION
    Hash::MultiValue is an object (and a plain hash reference) that may
    contain multiple values per key, inspired by MultiDict of WebOb.

WHY THIS MODULE
    In a typical web application, the request parameters (a.k.a CGI
    parameters) can be single value or multi values. Using CGI.pm style
    "param" is one way to deal with this problem (and it is good), but
    there's another approach to convert parameters into a hash reference,
    like Catalyst's "$c->req->parameters" does, and it sucks.

    Why? Because the value could be just a scalar if there is one value and
    an array ref if there are multiple, depending on *user input* rather
    than *how you code it*. So your code should always be like this to be
    defensive:

      my $p = $c->req->parameters;
      my @maybe_multi = ref $p->{m} eq 'ARRAY' ? @{$p->{m}} : ($p->{m});
      my $must_single = ref $p->{m} eq 'ARRAY' ? $p->{m}->[0] : $p->{m};

    Otherwise you'll get a random runtime exception of *Can't use string as
    an ARRAY ref* or get stringified array *ARRAY(0xXXXXXXXXX)* as a string,
    *depending on user input* and which is miserable and insecure.

    This module provides a solution to this by making it behave like a
    single value hash reference, but also has an API to get multiple values
    on demand, explicitly.

HOW THIS WORKS
    The object returned by "new" is a blessed hash reference that contains
    the last entry of the same key if there are multiple values, but it also
    keeps the original pair state in the object tracker (a.k.a inside out
    objects) and allows you to access the original pairs and multiple values
    via the method calls, such as "get_all" or "flatten".

    This module does not use "tie" or overload and is quite fast.

    Yes, there is Tie::Hash::MultiValue and this module tries to solve
    exactly the same problem, but using a different implementation.

AUTHOR
    Tatsuhiko Miyagawa <miyagawa@bulknews.net>

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

SEE ALSO
    <http://pythonpaste.org/webob/#multidict> Tie::Hash::MultiValue

Something went wrong with that request. Please try again.