• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

lib/Hash/H17-Feb-2015-609232

t/H17-Feb-2015-263193

tools/H17-Feb-2015-3630

xt/H17-Feb-2015-2622

ChangesH A D17-Feb-20151.7 KiB5639

LICENSEH A D17-Feb-201518 KiB380292

MANIFESTH A D17-Feb-2015380 2726

META.jsonH A D17-Feb-20151.7 KiB7169

META.ymlH A D17-Feb-2015983 3736

Makefile.PLH A D17-Feb-20151 KiB5336

READMEH A D17-Feb-20159.3 KiB286203

cpanfileH A D17-Feb-201577 64

dist.iniH A D17-Feb-201531 32

README

1NAME
2    Hash::MultiValue - Store multiple values per key
3
4SYNOPSIS
5      use Hash::MultiValue;
6
7      my $hash = Hash::MultiValue->new(
8          foo => 'a',
9          foo => 'b',
10          bar => 'baz',
11      );
12
13      # $hash is an object, but can be used as a hashref and DWIMs!
14      my $foo = $hash->{foo};         # 'b' (the last entry)
15      my $foo = $hash->get('foo');    # 'b' (always, regardless of context)
16      my @foo = $hash->get_all('foo'); # ('a', 'b')
17
18      keys %$hash; # ('foo', 'bar')    not guaranteed to be ordered
19      $hash->keys; # ('foo', 'foo', 'bar') guaranteed to be ordered
20
21DESCRIPTION
22    Hash::MultiValue is an object (and a plain hash reference) that may
23    contain multiple values per key, inspired by MultiDict of WebOb.
24
25RATIONALE
26    In a typical web application, the request parameters (a.k.a CGI
27    parameters) can be single value or multi values. Using CGI.pm style
28    "param" is one way to deal with this problem (and it is good, as long as
29    you're aware of its list context gotcha), but there's another approach
30    to convert parameters into a hash reference, like Catalyst's
31    "$c->req->parameters" does, and it sucks.
32
33    Why? Because the value could be just a scalar if there is one value and
34    an array ref if there are multiple, depending on *user input* rather
35    than *how you code it*. So your code should always be like this to be
36    defensive:
37
38      my $p = $c->req->parameters;
39      my @maybe_multi = ref $p->{m} eq 'ARRAY' ? @{$p->{m}} : ($p->{m});
40      my $must_single = ref $p->{m} eq 'ARRAY' ? $p->{m}->[0] : $p->{m};
41
42    Otherwise you'll get a random runtime exception of *Can't use string as
43    an ARRAY ref* or get stringified array *ARRAY(0xXXXXXXXXX)* as a string,
44    *depending on user input* and that is miserable and insecure.
45
46    This module provides a solution to this by making it behave like a
47    single value hash reference, but also has an API to get multiple values
48    on demand, explicitly.
49
50HOW THIS WORKS
51    The object returned by "new" is a blessed hash reference that contains
52    the last entry of the same key if there are multiple values, but it also
53    keeps the original pair state in the object tracker (a.k.a inside out
54    objects) and allows you to access the original pairs and multiple values
55    via the method calls, such as "get_all" or "flatten".
56
57    This module does not use "tie" or overload and is quite fast.
58
59    Yes, there is Tie::Hash::MultiValue and this module tries to solve
60    exactly the same problem, but using a different implementation.
61
62UPDATING CONTENTS
63    When you update the content of the hash, DO NOT UPDATE using the hash
64    reference interface: this won't write through to the tracking object.
65
66      my $hash = Hash::MultiValue->new(...);
67
68      # WRONG
69      $hash->{foo} = 'bar';
70      delete $hash->{foo};
71
72      # Correct
73      $hash->add(foo => 'bar');
74      $hash->remove('foo');
75
76    See below for the list of updating methods.
77
78METHODS
79    new
80          $hash = Hash::MultiValue->new(@pairs);
81
82        Creates a new object that can be treated as a plain hash reference
83        as well.
84
85    get
86          $value = $hash->get($key);
87          $value = $hash->{$key};
88
89        Returns a single value for the given $key. If there are multiple
90        values, the last one (not first one) is returned. See below for why.
91
92        Note that this always returns the single element as a scalar,
93        regardless of its context, unlike CGI.pm's "param" method etc.
94
95    get_one
96          $value = $hash->get_one($key);
97
98        Returns a single value for the given $key. This method croaks if
99        there is no value or multiple values associated with the key, so you
100        should wrap it with eval or modules like Try::Tiny.
101
102    get_all
103          @values = $hash->get_all($key);
104
105        Returns a list of values for the given $key. This method always
106        returns a list regardless of its context. If there is no value
107        attached, the result will be an empty list.
108
109    keys
110          @keys = $hash->keys;
111
112        Returns a list of all keys, including duplicates (see the example in
113        the "SYNOPSIS").
114
115        If you want only unique keys, use "keys %$hash", as normal.
116
117    values
118          @values = $hash->values;
119
120        Returns a list of all values, in the same order as "$hash->keys".
121
122    set
123          $hash->set($key [, $value ... ]);
124
125        Changes the stored value(s) of the given $key. This removes or adds
126        pairs as necessary to store the new list but otherwise preserves
127        order of existing pairs. "$hash->{$key}" is updated to point to the
128        last value.
129
130    add
131          $hash->add($key, $value [, $value ... ]);
132
133        Appends a new value to the given $key. This updates the value of
134        "$hash->{$key}" as well so it always points to the last value.
135
136    remove
137          $hash->remove($key);
138
139        Removes a key and associated values for the given $key.
140
141    clear
142          $hash->clear;
143
144        Clears the hash to be an empty hash reference.
145
146    flatten
147          @pairs = $hash->flatten;
148
149        Gets pairs of keys and values. This should be exactly the same pairs
150        which are given to "new" method unless you updated the data.
151
152    each
153          $hash->each($code);
154
155          # e.g.
156          $hash->each(sub { print "$_[0] = $_[1]\n" });
157
158        Calls $code once for each "($key, $value)" pair. This is a more
159        convenient alternative to calling "flatten" and then iterating over
160        it two items at a time.
161
162        Inside $code, $_ contains the current iteration through the loop,
163        starting at 0. For example:
164
165          $hash = Hash::MultiValue->new(a => 1, b => 2, c => 3, a => 4);
166
167          $hash->each(sub { print "$_: $_[0] = $_[1]\n" });
168          # 0: a = 1
169          # 1: b = 2
170          # 2: c = 3
171          # 3: a = 4
172
173        Be careful not to change @_ inside your coderef! It will update the
174        tracking object but not the plain hash. In the future, this
175        limitation *may* be removed.
176
177    clone
178          $new = $hash->clone;
179
180        Creates a new Hash::MultiValue object that represents the same data,
181        but obviously not sharing the reference. It's identical to:
182
183          $new = Hash::MultiValue->new($hash->flatten);
184
185    as_hashref
186          $copy = $hash->as_hashref;
187
188        Creates a new plain (unblessed) hash reference where a value is a
189        single scalar. It's identical to:
190
191          $copy = +{%$hash};
192
193    as_hashref_mixed, mixed
194          $mixed = $hash->as_hashref_mixed;
195          $mixed = $hash->mixed;
196
197        Creates a new plain (unblessed) hash reference where the value is a
198        single scalar, or an array ref when there are multiple values for a
199        same key. Handy to create a hash reference that is often used in web
200        application frameworks request objects such as Catalyst. Ths method
201        does exactly the opposite of "from_mixed".
202
203    as_hashref_multi, multi
204          $multi = $hash->as_hashref_multi;
205          $multi = $hash->multi;
206
207        Creates a new plain (unblessed) hash reference where values are all
208        array references, regardless of there are single or multiple values
209        for a same key.
210
211    from_mixed
212          $hash = Hash::MultiValue->from_mixed({
213              foo => [ 'a', 'b' ],
214              bar => 'c',
215          });
216
217        Creates a new object out of a hash reference where the value is
218        single or an array ref depending on the number of elements. Handy to
219        convert from those request objects used in web frameworks such as
220        Catalyst. This method does exactly the opposite of
221        "as_hashref_mixed".
222
223WHY LAST NOT FIRST?
224    You might wonder why this module uses the *last* value of the same key
225    instead of *first*. There's no strong reasoning on this decision since
226    one is as arbitrary as the other, but this is more consistent to what
227    Perl does:
228
229      sub x {
230          return ('a', 'b', 'c');
231      }
232
233      my $x = x(); # $x = 'c'
234
235      my %a = ( a => 1 );
236      my %b = ( a => 2 );
237
238      my %m = (%a, %b); # $m{a} = 2
239
240    When perl gets a list in a scalar context it gets the last entry. Also
241    if you merge hashes having a same key, the last one wins.
242
243NOTES ON ref
244    If you pass this MultiValue hash object to some upstream functions that
245    you can't control and does things like:
246
247      if (ref $args eq 'HASH') {
248          ...
249      }
250
251    because this is a blessed hash reference it doesn't match and would
252    fail. To avoid that you should call "as_hashref" to get a *finalized* (=
253    non-blessed) hash reference.
254
255    You can also use UNIVERSAL::ref to make it work magically:
256
257      use UNIVERSAL::ref;    # before loading Hash::MultiValue
258      use Hash::MultiValue;
259
260    and then all "ref" calls to Hash::MultiValue objects will return *HASH*.
261
262THREAD SAFETY
263    Prior to version 0.09, this module wasn't safe in a threaded
264    environment, including win32 fork() emulation. Versions newer than 0.09
265    is considered thread safe.
266
267AUTHOR
268    Tatsuhiko Miyagawa <miyagawa@bulknews.net>
269
270    Aristotle Pagaltzis
271
272    Hans Dieter Pearcey
273
274    Thanks to Michael Peters for the suggestion to use inside-out objects
275    instead of tie.
276
277LICENSE
278    This library is free software; you can redistribute it and/or modify it
279    under the same terms as Perl itself.
280
281SEE ALSO
282    *   <http://pythonpaste.org/webob/#multidict>
283
284    *   Tie::Hash::MultiValue
285
286