.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Hash::MultiValue 3pm" .TH Hash::MultiValue 3pm "2013-06-02" "perl v5.18.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Hash::MultiValue \- Store multiple values per key .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Hash::MultiValue; \& \& my $hash = Hash::MultiValue\->new( \& foo => \*(Aqa\*(Aq, \& foo => \*(Aqb\*(Aq, \& bar => \*(Aqbaz\*(Aq, \& ); \& \& # $hash is an object, but can be used as a hashref and DWIMs! \& my $foo = $hash\->{foo}; # \*(Aqb\*(Aq (the last entry) \& my $foo = $hash\->get(\*(Aqfoo\*(Aq); # \*(Aqb\*(Aq (always, regardless of context) \& my @foo = $hash\->get_all(\*(Aqfoo\*(Aq); # (\*(Aqa\*(Aq, \*(Aqb\*(Aq) \& \& keys %$hash; # (\*(Aqfoo\*(Aq, \*(Aqbar\*(Aq) not guaranteed to be ordered \& $hash\->keys; # (\*(Aqfoo\*(Aq, \*(Aqfoo\*(Aq, \*(Aqbar\*(Aq) guaranteed to be ordered .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Hash::MultiValue is an object (and a plain hash reference) that may contain multiple values per key, inspired by MultiDict of WebOb. .SH "RATIONALE" .IX Header "RATIONALE" In a typical web application, the request parameters (a.k.a \s-1CGI\s0 parameters) can be single value or multi values. Using \s-1CGI\s0.pm style \&\f(CW\*(C`param\*(C'\fR is one way to deal with this problem (and it is good, as long as you're aware of its list context gotcha), but there's another approach to convert parameters into a hash reference, like Catalyst's \&\f(CW\*(C`$c\->req\->parameters\*(C'\fR does, and it \fBsucks\fR. .PP Why? Because the value could be just a scalar if there is one value and an array ref if there are multiple, depending on \fIuser input\fR rather than \fIhow you code it\fR. So your code should always be like this to be defensive: .PP .Vb 3 \& my $p = $c\->req\->parameters; \& my @maybe_multi = ref $p\->{m} eq \*(AqARRAY\*(Aq ? @{$p\->{m}} : ($p\->{m}); \& my $must_single = ref $p\->{m} eq \*(AqARRAY\*(Aq ? $p\->{m}\->[0] : $p\->{m}; .Ve .PP Otherwise you'll get a random runtime exception of \fICan't use string as an \s-1ARRAY\s0 ref\fR or get stringified array \fI\s-1ARRAY\s0(0xXXXXXXXXX)\fR as a string, \fIdepending on user input\fR and that is miserable and insecure. .PP This module provides a solution to this by making it behave like a single value hash reference, but also has an \s-1API\s0 to get multiple values on demand, explicitly. .SH "HOW THIS WORKS" .IX Header "HOW THIS WORKS" The object returned by \f(CW\*(C`new\*(C'\fR 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 \f(CW\*(C`get_all\*(C'\fR or \f(CW\*(C`flatten\*(C'\fR. .PP This module does not use \f(CW\*(C`tie\*(C'\fR or overload and is quite fast. .PP Yes, there is Tie::Hash::MultiValue and this module tries to solve exactly the same problem, but using a different implementation. .SH "UPDATING CONTENTS" .IX Header "UPDATING CONTENTS" When you update the content of the hash, \fB\s-1DO NOT UPDATE\s0\fR using the hash reference interface: this won't write through to the tracking object. .PP .Vb 1 \& my $hash = Hash::MultiValue\->new(...); \& \& # WRONG \& $hash\->{foo} = \*(Aqbar\*(Aq; \& delete $hash\->{foo}; \& \& # Correct \& $hash\->add(foo => \*(Aqbar\*(Aq); \& $hash\->remove(\*(Aqfoo\*(Aq); .Ve .PP See below for the list of updating methods. .SH "METHODS" .IX Header "METHODS" .IP "new" 4 .IX Item "new" .Vb 1 \& $hash = Hash::MultiValue\->new(@pairs); .Ve .Sp Creates a new object that can be treated as a plain hash reference as well. .IP "get" 4 .IX Item "get" .Vb 2 \& $value = $hash\->get($key); \& $value = $hash\->{$key}; .Ve .Sp Returns a single value for the given \f(CW$key\fR. If there are multiple values, the last one (not first one) is returned. See below for why. .Sp Note that this \fBalways\fR returns the single element as a scalar, regardless of its context, unlike \s-1CGI\s0.pm's \f(CW\*(C`param\*(C'\fR method etc. .IP "get_one" 4 .IX Item "get_one" .Vb 1 \& $value = $hash\->get_one($key); .Ve .Sp Returns a single value for the given \f(CW$key\fR. This method \fBcroaks\fR if there is no value or multiple values associated with the key, so you should wrap it with eval or modules like Try::Tiny. .IP "get_all" 4 .IX Item "get_all" .Vb 1 \& @values = $hash\->get_all($key); .Ve .Sp Returns a list of values for the given \f(CW$key\fR. This method \fBalways\fR returns a list regardless of its context. If there is no value attached, the result will be an empty list. .IP "keys" 4 .IX Item "keys" .Vb 1 \& @keys = $hash\->keys; .Ve .Sp Returns a list of all keys, including duplicates (see the example in the \&\*(L"\s-1SYNOPSIS\*(R"\s0). .Sp If you want only unique keys, use \f(CW\*(C`keys %$hash\*(C'\fR, as normal. .IP "values" 4 .IX Item "values" .Vb 1 \& @values = $hash\->values; .Ve .Sp Returns a list of all values, in the same order as \f(CW\*(C`$hash\->keys\*(C'\fR. .IP "set" 4 .IX Item "set" .Vb 1 \& $hash\->set($key [, $value ... ]); .Ve .Sp Changes the stored value(s) of the given \f(CW$key\fR. This removes or adds pairs as necessary to store the new list but otherwise preserves order of existing pairs. \f(CW\*(C`$hash\->{$key}\*(C'\fR is updated to point to the last value. .IP "add" 4 .IX Item "add" .Vb 1 \& $hash\->add($key, $value [, $value ... ]); .Ve .Sp Appends a new value to the given \f(CW$key\fR. This updates the value of \&\f(CW\*(C`$hash\->{$key}\*(C'\fR as well so it always points to the last value. .IP "remove" 4 .IX Item "remove" .Vb 1 \& $hash\->remove($key); .Ve .Sp Removes a key and associated values for the given \f(CW$key\fR. .IP "clear" 4 .IX Item "clear" .Vb 1 \& $hash\->clear; .Ve .Sp Clears the hash to be an empty hash reference. .IP "flatten" 4 .IX Item "flatten" .Vb 1 \& @pairs = $hash\->flatten; .Ve .Sp Gets pairs of keys and values. This should be exactly the same pairs which are given to \f(CW\*(C`new\*(C'\fR method unless you updated the data. .IP "each" 4 .IX Item "each" .Vb 1 \& $hash\->each($code); \& \& # e.g. \& $hash\->each(sub { print "$_[0] = $_[1]\en" }); .Ve .Sp Calls \f(CW$code\fR once for each \f(CW\*(C`($key, $value)\*(C'\fR pair. This is a more convenient alternative to calling \f(CW\*(C`flatten\*(C'\fR and then iterating over it two items at a time. .Sp Inside \f(CW$code\fR, \f(CW$_\fR contains the current iteration through the loop, starting at 0. For example: .Sp .Vb 1 \& $hash = Hash::MultiValue\->new(a => 1, b => 2, c => 3, a => 4); \& \& $hash\->each(sub { print "$_: $_[0] = $_[1]\en" }); \& # 0: a = 1 \& # 1: b = 2 \& # 2: c = 3 \& # 3: a = 4 .Ve .Sp Be careful \fBnot\fR to change \f(CW@_\fR inside your coderef! It will update the tracking object but not the plain hash. In the future, this limitation \fImay\fR be removed. .IP "clone" 4 .IX Item "clone" .Vb 1 \& $new = $hash\->clone; .Ve .Sp Creates a new Hash::MultiValue object that represents the same data, but obviously not sharing the reference. It's identical to: .Sp .Vb 1 \& $new = Hash::MultiValue\->new($hash\->flatten); .Ve .IP "as_hashref" 4 .IX Item "as_hashref" .Vb 1 \& $copy = $hash\->as_hashref; .Ve .Sp Creates a new plain (unblessed) hash reference where a value is a single scalar. It's identical to: .Sp .Vb 1 \& $copy = +{%$hash}; .Ve .IP "as_hashref_mixed, mixed" 4 .IX Item "as_hashref_mixed, mixed" .Vb 2 \& $mixed = $hash\->as_hashref_mixed; \& $mixed = $hash\->mixed; .Ve .Sp Creates a new plain (unblessed) hash reference where the value is a single scalar, or an array ref when there are multiple values for a same key. Handy to create a hash reference that is often used in web application frameworks request objects such as Catalyst. Ths method does exactly the opposite of \f(CW\*(C`from_mixed\*(C'\fR. .IP "as_hashref_multi, multi" 4 .IX Item "as_hashref_multi, multi" .Vb 2 \& $multi = $hash\->as_hashref_multi; \& $multi = $hash\->multi; .Ve .Sp Creates a new plain (unblessed) hash reference where values are all array references, regardless of there are single or multiple values for a same key. .IP "from_mixed" 4 .IX Item "from_mixed" .Vb 4 \& $hash = Hash::MultiValue\->from_mixed({ \& foo => [ \*(Aqa\*(Aq, \*(Aqb\*(Aq ], \& bar => \*(Aqc\*(Aq, \& }); .Ve .Sp Creates a new object out of a hash reference where the value is single or an array ref depending on the number of elements. Handy to convert from those request objects used in web frameworks such as Catalyst. This method does exactly the opposite of \f(CW\*(C`as_hashref_mixed\*(C'\fR. .SH "WHY LAST NOT FIRST?" .IX Header "WHY LAST NOT FIRST?" You might wonder why this module uses the \fIlast\fR value of the same key instead of \fIfirst\fR. There's no strong reasoning on this decision since one is as arbitrary as the other, but this is more consistent to what Perl does: .PP .Vb 3 \& sub x { \& return (\*(Aqa\*(Aq, \*(Aqb\*(Aq, \*(Aqc\*(Aq); \& } \& \& my $x = x(); # $x = \*(Aqc\*(Aq \& \& my %a = ( a => 1 ); \& my %b = ( a => 2 ); \& \& my %m = (%a, %b); # $m{a} = 2 .Ve .PP When perl gets a list in a scalar context it gets the last entry. Also if you merge hashes having a same key, the last one wins. .SH "NOTES ON ref" .IX Header "NOTES ON ref" If you pass this MultiValue hash object to some upstream functions that you can't control and does things like: .PP .Vb 3 \& if (ref $args eq \*(AqHASH\*(Aq) { \& ... \& } .Ve .PP because this is a blessed hash reference it doesn't match and would fail. To avoid that you should call \f(CW\*(C`as_hashref\*(C'\fR to get a \&\fIfinalized\fR (= non-blessed) hash reference. .PP You can also use UNIVERSAL::ref to make it work magically: .PP .Vb 2 \& use UNIVERSAL::ref; # before loading Hash::MultiValue \& use Hash::MultiValue; .Ve .PP and then all \f(CW\*(C`ref\*(C'\fR calls to Hash::MultiValue objects will return \fI\s-1HASH\s0\fR. .SH "THREAD SAFETY" .IX Header "THREAD SAFETY" Prior to version 0.09, this module wasn't safe in a threaded environment, including win32 \fIfork()\fR emulation. Versions newer than 0.09 is considered thread safe. .SH "AUTHOR" .IX Header "AUTHOR" Tatsuhiko Miyagawa .PP Aristotle Pagaltzis .PP Hans Dieter Pearcey .PP Thanks to Michael Peters for the suggestion to use inside-out objects instead of tie. .SH "LICENSE" .IX Header "LICENSE" This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "\(bu" 4 .IP "\(bu" 4 Tie::Hash::MultiValue