File Coverage

blib/lib/Hash/Map.pm
Criterion Covered Total %
statement 231 238 97.0
branch 35 52 67.3
condition 2 3 66.6
subroutine 65 70 92.8
pod 46 46 100.0
total 379 409 92.6


line stmt bran cond sub pod time code
1             package Hash::Map; ## no critic (TidyCode)
2              
3 3     3   799527 use strict;
  3         9  
  3         125  
4 3     3   20 use warnings;
  3         6  
  3         155  
5              
6             our $VERSION = '0.014';
7              
8 3     3   19 use Carp qw(confess);
  3         8  
  3         157  
9 3     3   2635 use Clone qw(clone);
  3         13387  
  3         226  
10 3     3   3306 use Perl6::Export::Attrs;
  3         41437  
  3         34  
11 3     3   199 use Scalar::Util qw(blessed);
  3         12  
  3         239  
12 3     3   2987 use Try::Tiny;
  3         15257  
  3         8261  
13              
14             sub new {
15 37     37 1 6027 return bless
16             {
17             source => {},
18             target => {},
19             },
20             shift;
21             }
22              
23             sub _hashref {
24 183     183   288 my ($self, $key, $hashref) = @_;
25              
26 183 100       407 if ( defined $hashref ) {
27 59 50       163 ref $hashref eq 'HASH'
28             or confess 'Hash reference expected';
29 59 100       204 if ( ! blessed $self ) {
30 12         43 $self = $self->new; # this method used as constructor
31             }
32 59         135 $self->{$key} = $hashref;
33 59         236 return $self;
34             }
35              
36 124         741 return $self->{$key};
37             }
38              
39             sub _hash {
40 21     21   58 my ($self, $key, @more) = @_;
41              
42             @more
43 21 100       101 and return $self->_set_hash($key, @more);
44              
45 3         5 return %{ $self->_hashref($key) };
  3         35  
46             }
47              
48             sub _set_hash {
49 34     34   86 my ($self, $key, @more) = @_;
50              
51 34         45 my $hashref;
52             try {
53 34     34   1416 $hashref = { @more };
54             }
55             catch {
56 0     0   0 confess 'Hash expected ', $_;
57 34         246 };
58 34 100       605 if ( ! blessed $self ) {
59 17         47 $self = $self->new; # this method used as constructor
60             }
61 34         97 $self->_hashref($key, $hashref);
62              
63 34         201 return $self;
64             }
65              
66             ## no critic (ArgUnpacking);
67 55     55 1 171 sub source_ref { return shift->_hashref(source => @_) }
68 87     87 1 278 sub target_ref { return shift->_hashref(target => @_) }
69 2     2 1 8 sub set_source_ref { return shift->_hashref(source => @_) }
70 2     2 1 9 sub set_target_ref { return shift->_hashref(target => @_) }
71 9     9 1 1029 sub source { return shift->_hash(source => @_) }
72 12     12 1 11236 sub target { return shift->_hash(target => @_) }
73 8     8 1 14281 sub set_source { return shift->_set_hash(source => @_) }
74 8     8 1 28 sub set_target { return shift->_set_hash(target => @_) }
75              
76 2     2 1 8 sub source_keys { return keys %{ shift->source_ref } }
  2         6  
77 2     2 1 3 sub target_keys { return keys %{ shift->target_ref } }
  2         7  
78 2     2 1 8 sub source_values { return values %{ shift->source_ref } }
  2         7  
79 2     2 1 3 sub target_values { return values %{ shift->target_ref } }
  2         6  
80              
81 1     1 1 4 sub source_keys_ref { return [ shift->source_keys ] }
82 1     1 1 5 sub target_keys_ref { return [ shift->target_keys ] }
83 1     1 1 3 sub source_values_ref { return [ shift->source_values ] }
84 1     1 1 5 sub target_values_ref { return [ shift->target_values ] }
85              
86 2     2 1 12 sub exists_source { return exists shift->source_ref->{ ( shift )} }
87 2     2 1 7 sub exists_target { return exists shift->target_ref->{ ( shift ) } }
88             ## use critic (ArgUnpacking);
89              
90             sub combine {
91 2     2 1 5 my ($self, @hash_maps) = @_;
92              
93 2 100       11 if ( ! blessed $self ) {
94 1         4 $self = $self->new; # this method used as constructor
95             }
96 2         7 for my $hash_map (@hash_maps) {
97 2         6 $self->merge_hashref( $hash_map->target_ref );
98             }
99              
100 2         8 return $self;
101             }
102              
103             sub clone_source {
104 1     1 1 2 my $self = shift;
105              
106 1         4 $self->source_ref( clone( $self->source_ref ) );
107              
108 1         4 return $self;
109             }
110              
111             sub clone_target {
112 1     1 1 2 my $self = shift;
113              
114 1         4 $self->target_ref( clone( $self->target_ref ) );
115              
116 1         3 return $self;
117             }
118              
119             sub delete_keys_ref {
120 2     2 1 4 my ($self, $keys_ref) = @_;
121              
122 2 50       8 ref $keys_ref eq 'ARRAY'
123             or confess 'Array reference expected';
124 2         2 delete @{ $self->target_ref }{ @{$keys_ref} };
  2         6  
  2         3  
125              
126 2         7 return $self;
127             }
128              
129             sub delete_keys {
130 1     1 1 3 my ($self, @keys) = @_;
131              
132 1         5 return $self->delete_keys_ref(\@keys);
133             }
134              
135             # begin from source to target
136              
137             sub copy_keys_ref {
138 7     7 1 12 my ($self, $keys_ref, $code_ref) = @_;
139              
140 7 50       23 ref $keys_ref eq 'ARRAY'
141             or confess 'Array reference expected';
142 7 100       19 if ( ref $code_ref eq 'CODE' ) {
143             return $self->map_keys_ref({
144             map { ## no critic (MutatingListFunctions VoidMap)
145 2         811 $_ => do {
  1         2  
146 2         4 local $_ = $_;
147 2         6 scalar $code_ref->($self);
148             };
149 1         3 } @{$keys_ref}
150             });
151             }
152              
153 6         15 @{ $self->target_ref }{ @{$keys_ref} }
  6         10  
  6         14  
154 6         10 = @{ $self->source_ref }{ @{$keys_ref} };
  6         16  
155              
156 6         18 return $self;
157             }
158              
159             sub copy_keys {
160 7     7 1 15 my ($self, @keys) = @_;
161              
162 7 100 66     45 if ( @keys && ref $keys[-1] eq 'CODE' ) {
163 2         2 my $code_ref = pop @keys;
164             return $self->map_keys_ref({
165             map { ## no critic (MutatingListFunctions VoidMap)
166 2         12 $_ => do {
  4         11761  
167 4         6 local $_ = $_;
168 4         12 scalar $code_ref->($self);
169             };
170             } @keys
171             });
172             }
173              
174 5         18 return $self->copy_keys_ref(\@keys);
175             }
176              
177             sub map_keys_ref {
178 7     7 1 2065 my ($self, $map_ref) = @_;
179              
180 7 50       27 ref $map_ref eq 'HASH'
181             or confess 'Hash reference expected';
182 7         17 @{ $self->target_ref }{ values %{$map_ref} }
  7         14  
  7         20  
183 7         10 = @{ $self->source_ref }{ keys %{$map_ref} };
  7         22  
184              
185 7         32 return $self;
186             }
187              
188             sub map_keys {
189 3     3 1 7 my ($self, @more) = @_;
190              
191 3         4 my $map_ref;
192             try {
193 3     3   109 $map_ref = { @more };
194             }
195             catch {
196 0     0   0 confess 'Hash expected ', $_;
197 3         21 };
198              
199 3         50 return $self->map_keys_ref($map_ref);
200             }
201              
202             # begin copy from source to target
203              
204             sub merge_hashref {
205 4     4 1 7 my ($self, $hashref) = @_;
206              
207 4 50       13 ref $hashref eq 'HASH'
208             or confess 'Hash reference expected';
209 4         5 @{ $self->target_ref }{ keys %{$hashref} } = values %{$hashref};
  4         9  
  4         8  
  4         9  
210              
211 4         13 return $self;
212             }
213              
214             sub merge_hash {
215 1     1 1 3 my ($self, @more) = @_;
216              
217 1         3 my $hashref;
218             try {
219 1     1   33 $hashref = { @more };
220             }
221             catch {
222 0     0   0 confess 'Hash expected ', $_;
223 1         7 };
224              
225 1         15 return $self->merge_hashref($hashref);
226             }
227              
228             sub modify_ref {
229 5     5 1 8 my ($self, $modify_ref) = @_;
230              
231 5 50       19 ref $modify_ref eq 'HASH'
232             or confess 'Hash reference expected';
233 5         14 my $target_ref = $self->target_ref;
234 5         8 while ( my ($key, $code_ref) = each %{$modify_ref} ) {
  14         3301  
235 9         17 local $_ = $target_ref->{$key};
236 9         25 $target_ref->{$key} = $code_ref->($self);
237             }
238              
239 5         26 return $self;
240             }
241              
242             # end copy from source to target
243              
244             sub modify {
245 2     2 1 6 my ($self, @more) = @_;
246              
247 2         4 my $modify_ref;
248             try {
249 2     2   90 $modify_ref = { @more };
250             }
251             catch {
252 0     0   0 confess 'Hash expected ', $_;
253 2         15 };
254              
255 2         38 return $self->modify_ref($modify_ref);
256             }
257              
258             # begin copy from source to target
259              
260             sub copy_modify_ref {
261 2     2 1 3 my ($self, $copy_modify_ref) = @_;
262              
263 2 50       7 ref $copy_modify_ref eq 'HASH'
264             or confess 'Hash reference expected';
265 2         3 $self->copy_keys( keys %{$copy_modify_ref} );
  2         44  
266              
267 2         8 return $self->modify_ref($copy_modify_ref);
268             }
269              
270             sub copy_modify {
271 1     1 1 3 my ($self, @more) = @_;
272              
273 1         2 my $copy_modify_ref;
274             try {
275 1     1   29 $copy_modify_ref = { @more };
276             }
277             catch {
278 0     0   0 confess 'Hash expected ', $_;
279 1         7 };
280              
281 1         14 return $self->copy_modify_ref($copy_modify_ref);
282             }
283              
284             sub copy_modify_identical_ref {
285 2     2 1 3 my ($self, $keys_ref, $code_ref) = @_;
286              
287 2 50       7 ref $keys_ref eq 'ARRAY'
288             or confess 'Array reference for keys expected';
289 2 50       5 ref $code_ref eq 'CODE'
290             or confess 'Code reference for modify expected';
291 2         5 my $source_ref = $self->source_ref;
292 2         8 my $target_ref = $self->target_ref;
293 2         14 for my $key ( @{$keys_ref} ) {
  2         5  
294 4         1463 $target_ref->{$key} = $source_ref->{$key};
295 4         7 local $_ = $target_ref->{$key};
296 4         12 $target_ref->{$key} = $code_ref->($self, $key);
297             }
298              
299 2         1318 return $self;
300             }
301              
302             sub copy_modify_identical {
303 1     1 1 3 my ($self, @keys) = @_;
304              
305 1         2 my $code_ref = pop @keys;
306 1 50       6 ref $code_ref eq 'CODE'
307             or confess 'Code reference as last parameter expected';
308              
309 1         5 return $self->copy_modify_identical_ref(\@keys, $code_ref);
310             }
311              
312             sub map_modify_ref {
313 2     2 1 4 my ($self, $map_modify_ref) = @_;
314              
315 2 50       9 ref $map_modify_ref eq 'ARRAY'
316             or confess 'Array reference expected';
317              
318 0         0 @{$map_modify_ref} % 3 ## no critic (MagicNumber)
  2         7  
319             and confess
320 2 50       3 scalar @{$map_modify_ref},
321             ' elements in array are not a group of 3';
322 2         4 my @map_modify = @{$map_modify_ref};
  2         7  
323 2         6 my $source_ref = $self->source_ref;
324 2         6 my $target_ref = $self->target_ref;
325 2         9 while ( my ($source_key, $target_key, $code_ref) = splice @map_modify, 0, 3 ) { ## no critic (MagicNumber)
326 4         1298 $target_ref->{$target_key} = $source_ref->{$source_key};
327 4         7 local $_ = $target_ref->{$target_key};
328 4         14 $target_ref->{$target_key} = $code_ref->($self);
329             };
330              
331 2         22 return $self;
332             }
333              
334             sub map_modify {
335 1     1 1 4 my ($self, @map_modify) = @_;
336              
337 1         13 return $self->map_modify_ref(\@map_modify);
338             }
339              
340             sub map_modify_identical_ref {
341 2     2 1 5 my ($self, $hash_ref, $code_ref) = @_;
342              
343 2 50       6 ref $hash_ref eq 'HASH'
344             or confess 'Hash reference expected';
345 2 50       7 ref $code_ref eq 'CODE'
346             or confess 'Code reference as last parameter expected';
347 2         5 my $source_ref = $self->source_ref;
348 2         7 my $target_ref = $self->target_ref;
349 2         4 while ( my ($source_key, $target_key) = each %{$hash_ref} ) {
  6         2706  
350 4         6 $target_ref->{$target_key} = $source_ref->{$source_key};
351 4         9 local $_ = $target_ref->{$target_key};
352 4         12 $target_ref->{$target_key} = $code_ref->($self, $source_key, $target_key);
353             };
354              
355 2         10 return $self;
356             }
357              
358             sub map_modify_identical {
359 1     1 1 4 my ($self, @map_modify) = @_;
360              
361 1         3 my $code_ref = pop @map_modify;
362 1 50       4 @map_modify % 2
363             and confess
364             scalar @map_modify,
365             ' elements in array are not pairwise';
366 1 50       18 ref $code_ref eq 'CODE'
367             or confess 'Code reference as last parameter expected';
368              
369 1         7 return $self->map_modify_identical_ref({ @map_modify }, $code_ref);
370             }
371              
372             # end copy from source to target
373              
374             # begin iterator stuff
375              
376 6     6 1 1288 sub each_source { return each %{ shift->source_ref } }
  6         15  
377 6     6 1 1017 sub each_target { return each %{ shift->target_ref } }
  6         12  
378              
379             sub source_iterator {
380 1     1 1 6 my $self = shift;
381              
382             return sub {
383 3     3   1089 return $self->each_source;
384 1         6 };
385             }
386              
387             sub target_iterator {
388 1     1 1 588 my $self = shift;
389              
390             return sub {
391 3     3   1153 return $self->each_target;
392 1         7 };
393             }
394              
395             # end iterator stuff
396              
397             sub hashref_map :Export {
398 4     4 1 10 my ($source_ref, @more) = @_;
399              
400 4         16 my $self = Hash::Map->source_ref($source_ref);
401             ITEM:
402 4         9 for my $item (@more) {
403 5 100       14 if ( ref $item eq 'ARRAY' ) {
404 3         4 $self->copy_keys( @{$item} );
  3         10  
405 3         11 next ITEM;
406             }
407 2 50       6 if ( ref $item eq 'HASH' ) {
408 2         3 while ( my ($key, $value) = each %{$item} ) {
  5         15  
409 3 100       14 ref $value eq 'CODE'
410             ? $self->modify($key, $value)
411             : $self->map_keys($key, $value);
412             }
413 2         7 next ITEM;
414             }
415 0         0 confess 'Array- or hash reference expected';
416             }
417              
418 4         10 return $self->target_ref;
419 3     3   34 }
  3         6  
  3         35  
420              
421             sub hash_map :Export { ## no critic (ArgUnpacking)
422 1     1 1 19 return %{ hashref_map(@_) };
  1         6  
423 3     3   878 }
  3         7  
  3         19  
424              
425             # $Id$
426              
427             1;
428              
429             __END__
430              
431             =head1 NAME
432              
433             Hash::Map - Manipulate hashes map like
434              
435             =head1 VERSION
436              
437             0.014
438              
439             =head1 SYNOPSIS
440              
441             require Hash::Map;
442              
443             Instead of
444              
445             %hash = (
446             a => $other->{a},
447             b => $other->{b},
448             c => $other->{c},
449             d => $other->{d},
450             e => $other->{e},
451             f => 'bla bla',
452             );
453              
454             write with map
455              
456             %hash = (
457             (
458             map {
459             $_ => $other->{$_};
460             } 'a' .. 'e'
461             ),
462             f => 'bla bla',
463             );
464              
465             or more clear readable
466              
467             %hash = Hash::Map
468             ->source_ref($other)
469             ->copy_keys('a' .. 'e')
470             ->merge_hash(f => 'bla bla')
471             ->target;
472              
473             =head1 DESCRIPTION
474              
475             Often in code we find lots of copy/paste code
476             during prepare a hash or hash reference.
477             That data we got from other structures, objects or constants.
478              
479             =over
480              
481             =item *
482              
483             We map hashes that not match exactly to the expected API.
484              
485             =item *
486              
487             Or the method names, we call, matching not exactly to the hash keys.
488              
489             =item *
490              
491             Sometimes we forgot to write C<scalar>
492             if we call subroutines/methods for a hash value
493             and risk to have a value as key.
494              
495             =item *
496              
497             We use C<map>, C<for>, C<map>/C<push>
498             to build the expected hash or hash reference.
499              
500             =item *
501              
502             Accidentally we do not destroy the data we fetch.
503              
504             =item *
505              
506             We have to write C<defined>, C<? :> or C<do>.
507              
508             =back
509              
510             This Module lets you writing code without that copied noise.
511              
512             The goal of this module is to write clear code with less typing around.
513             Less typing for the user needs lots of specialized methods in this module.
514              
515             The code in the SYNOPSIS
516             is only a very simple but typical example to understand,
517             why that module was written.
518              
519             Look at your existing code for lots of similar lines of hash key/value pairs.
520             Then this module can help you.
521              
522             There is also a fuctional interface.
523             That is wrapped around the OO inferface.
524             Not all can be implemented functional.
525              
526             For more information read the L<Hash::Map::Tutorial|Hash::Map::Tutorial>.
527              
528             =head1 EXAMPLE
529              
530             Inside of this Distribution is a directory named example.
531             Run this *.pl files.
532              
533             =head1 SUBROUTINES/METHODS
534              
535             =head2 method new
536              
537             A simple constructor without any parameters.
538              
539             my $obj = Hash::Map->new;
540              
541             Typical you don't call method "new" directly.
542              
543             =head2 method source, source_ref, set_source and set_source_ref
544              
545             Set or get the source hash.
546              
547             Method "source" can not set an empty hash, but an empty hash is the default.
548             Otherwise use method "set_source".
549              
550             $obj = $obj->source(%source);
551             $obj = $obj->source_ref($source_hashref);
552             # if %source is or can be empty
553             $obj = $obj->set_source(%source);
554             # method exists for the sake of completeness
555             $obj = $obj->set_source_ref($target_ref);
556              
557             %source = $obj->source;
558             $source_hashref = $obj->source_ref;
559              
560             This methods are able to construct the object first.
561              
562             Hash::Map->source(...);
563             Hash::Map->source_ref(...);
564             Hash::Map->set_source(...);
565             Hash::Map->set_source_ref(...);
566              
567             =head2 method target, target_ref, set_target and set_target_ref
568              
569             Set or get the target hash.
570              
571             Method "target" can not set an empty hash, but an empty hash is the default.
572             Otherwise use method "set_target".
573              
574             $obj = $obj->target(%target);
575             $obj = $obj->target_ref($target_hashref);
576              
577             # if %target is or can be empty
578             $obj = $obj->set_target(%target);
579             # method exists for the sake of completeness
580             $obj = $obj->set_target_ref($target_ref);
581              
582             %target = $obj->target;
583             $target_hashref = $obj->target_ref;
584              
585             This methods are able to construct the object first.
586              
587             Hash::Map->target(...);
588             Hash::Map->target_ref(...);
589             Hash::Map->set_target(...);
590             Hash::Map->set_target_ref(...);
591              
592             Typical the source is set and not the target.
593             But it makes no sense to set the source
594             and copy then all from source.
595              
596             =head2 method source_keys, target_keys, source_keys_ref, target_keys_ref
597              
598             This methods get back all keys as array or array reference.
599              
600             @keys = $obj->source_keys;
601             @keys = $obj->target_keys;
602             $array_ref = $obj->source_keys_ref;
603             $array_ref = $obj->target_keys_ref;
604              
605             =head2 method source_values, target_values, source_values_ref, target_values_ref
606              
607             This methods get back all values as array or array reference.
608              
609             @values = $obj->source_values;
610             @values = $obj->target_values;
611             $array_ref = $obj->source_values_ref;
612             $array_ref = $obj->target_values_ref;
613              
614             =head2 method exists_source, exists_target
615              
616             This methods allows easy writing for exists.
617              
618             $boolean = $obj->exists_source($key);
619             $boolean = $obj->exists_target($key);
620              
621             =head2 method combine
622              
623             Merge targets of other Hash::Map objects into $obj target.
624              
625             $obj = $obj->combine(@hash_map_objects);
626              
627             This method is able to construct the object first.
628              
629             Hash::Map->combine(...);
630              
631             Typical used for clear code to prevent the change of the source hash/hashref.
632             It's strongly readable if source is set more than one time.
633              
634             =head2 method clone_source
635              
636             Using Module Clone to clone the source hash.
637              
638             $obj = $obj->clone_source;
639              
640             This method exists for the sake of completeness.
641              
642             =head2 method clone_target
643              
644             Using Module Clone to clone the target hash.
645              
646             $obj = $obj->clone_target;
647              
648             Only used after set of target hash reference
649             to prevent manpulations backwards.
650              
651             =head2 method delete_keys and delete_keys_ref
652              
653             Delete keys in target hash.
654              
655             $obj = $obj->delete_keys(@keys);
656             $obj = $obj->delete_keys_ref($keys_array_ref);
657              
658             =head2 method copy_keys and copy_keys_ref
659              
660             Copy data from source to target hash using keys.
661              
662             $obj = $obj->copy_keys(@keys);
663             $obj = $obj->copy_keys_ref($keys_array_ref);
664              
665             And rename all keys during copy.
666              
667             $obj = $obj->copy_keys(
668             @keys,
669             sub {
670             my $obj = shift;
671             my $key = $_;
672             return "new $key";
673             },
674             );
675             $obj = $obj->copy_keys_ref(
676             $keys_array_ref,
677             sub {
678             my $obj = shift;
679             my $key = $_;
680             return "new $key";
681             },
682             );
683              
684             The first parameter of the callback subroutine is the object itself.
685             The current key is in $_.
686             Return the new key.
687              
688             Replaces code like this:
689              
690             %target = (
691             a => $source->{a},
692             b => $source->{b},
693             ...
694             );
695             %target = (
696             p_a => $source->{a},
697             p_b => $source->{b},
698             ...
699             );
700              
701             =head2 method map_keys and map_keys_ref
702              
703             Copy data from source hash (key is key of map)
704             to target hash (key is value of map).
705              
706             $obj = $obj->map_keys(%map);
707             $obj = $obj->map_keys_ref($map_hashref);
708              
709             Replaces code like this:
710              
711             %target = (
712             a => $source->{z},
713             b => $source->{y},
714             ...
715             );
716              
717             =head2 method merge_hash and merge_hashref
718              
719             Merge the given hash into the target hash.
720              
721             $obj = $obj->merge_hash(%hash);
722             $obj = $obj->merge_hashref($hashref);
723              
724             Replaces code like this:
725              
726             %target = (
727             %hash,
728             ...
729             );
730              
731             =head2 method modify and modify_ref
732              
733             Modify the target hash inplace by given key and code for that.
734              
735             The first parameter of the callback subroutine is the object itself.
736             The old value of the target hash is in $_;
737             Return the new value.
738              
739             $obj = $obj->modify(
740             key1 => $code_ref1,
741             ...
742             );
743             $obj = $obj->modify_ref({
744             key1 => $code_ref1,
745             ...
746             });
747              
748             Typical the combinated methods are used:
749             "copy_modify",
750             "copy_modify_ref",
751             "copy_modify_identical",
752             "copy_modify_identical_ref",
753             "map_modify",
754             "map_modify_ref",
755             "map_modify_identical" and
756             "map_modify_identical_ref".
757              
758             =head2 method copy_modify and copy_modify_ref
759              
760             This is a combination of method "copy_keys" and "modify".
761              
762             The first parameter of the callback subroutine is the object itself.
763             The old value of the target hash is in $_;
764             Return the new value.
765              
766             $obj = $obj->copy_modify(
767             key1 => $code_ref1,
768             ...
769             );
770             $obj = $obj->copy_modify_ref({
771             key1 => $code_ref1,
772             ...
773             });
774              
775             It is not possible to rename all keys during copy.
776             Use method "map_modify" or "map_modify_ref" instead.
777              
778             This method exists for the sake of completeness.
779              
780             =head2 method copy_modify_identical and copy_modify_identical_ref
781              
782             This is another combination of method "copy_keys" and "modify".
783             All values are modified using a common code reference.
784              
785             The 1st parameter of the callback subroutine is the object itself.
786             The 2nd parameter is the key.
787             The old value of the target hash is in $_;
788             Return the new value.
789              
790             $obj = $obj->copy_modify_identical(
791             @keys,
792             $code_ref,
793             );
794             $obj = $obj->copy_modify_identical_ref(
795             $keys_array_ref,
796             $code_ref,
797             );
798              
799             It is not possible to rename all keys during copy.
800             Use method "map_modify_identical" or "map_modify_identical" instead.
801              
802             Replaces code like this:
803              
804             %target = (
805             a => $foo->bar('a'),
806             b => $foo->bar('b'),
807             ...
808             );
809             %target = (
810             a => $foo->a,
811             b => $foo->b,
812             ...
813             );
814              
815             =head2 method map_modify and map_modify_ref
816              
817             This is a combination of method "map_keys" and "modify".
818              
819             The first parameter of the callback subroutine is the object itself.
820             The old value of the target hash is in $_;
821             Return the new value.
822              
823             $obj = $obj->map_modify(
824             source_key1 => target_key1 => $code_ref1,
825             ...
826             );
827             $obj = $obj->map_modify_ref([
828             source_key1 => target_key1 => $code_ref1,
829             ...
830             ]);
831              
832             This method exists for the sake of completeness.
833              
834             =head2 method map_modify_identical and map_modify_identical_ref
835              
836             This is a combination of method "map_keys" and "modify".
837              
838             The 1st parameter of the callback subroutine is the object itself.
839             The 2nd parameter is the source key and the 3rd parameter is the target key.
840             The old value of the target hash is in $_;
841             Return the new value.
842              
843             $obj = $obj->map_modify_identical(
844             source_key1 => target_key1,
845             ...
846             $code_ref,
847             );
848             $obj = $obj->map_modify_identical_ref(
849             {
850             source_key1 => target_key1,
851             ...
852             },
853             $code_ref,
854             );
855              
856             Replaces code like this:
857              
858             %target = (
859             a => $foo->bar('z'),
860             b => $foo->bar('y'),
861             ...
862             );
863             %target = (
864             a => $foo->z,
865             b => $foo->y,
866             ...
867             );
868              
869             =head2 method each_source, each_target, source_iterator, target_iterator
870              
871             This methods allows to work with iterations.
872              
873             while ( my ($key, $value) = $self->each_source ) {
874             ...
875             }
876              
877             while ( my ($key, $value) = $self->each_target ) {
878             ...
879             }
880              
881             my $iterator_code = $self->source_iterator;
882             while ( my ($key, $value) = $iterator_code->() ) {
883             ...
884             }
885              
886             my $iterator_code = $self->target_iterator;
887             while ( my ($key, $value) = $iterator_code->() ) {
888             ...
889             }
890              
891             =head2 subroutine hash_map
892              
893             This subroutine is for the fuctional interface only.
894              
895             %target_hash = hash_map(
896             \%source_hash,
897             # The following references are sorted anyway.
898             # Running in order like written.
899             [ qw(key1 key2) ], # copy_keys from source to target hash
900             [ qw(key3 key4), $code_ref ], # copy_keys, code_ref to rename keys
901             {
902             source_key1 => 'target_key', # map_keys from source to target hash
903             source_key2 => $code_ref, # modify values in target hash
904             },
905             );
906              
907             =head2 subroutine hashref_map
908              
909             Similar, only the subroutine name and the return value has chenged.
910              
911             $target_hashref = hashref_map(
912             $source_hashref,
913             ...
914             );
915              
916             =head1 DIAGNOSTICS
917              
918             nothing
919              
920             =head1 CONFIGURATION AND ENVIRONMENT
921              
922             nothing
923              
924             =head1 DEPENDENCIES
925              
926             L<Carp|Carp>
927              
928             L<Clone|Clone>
929              
930             L<Perl6::Export::Attrs|Perl6::Export::Attrs>
931              
932             L<Scalar::Util|Scalar::Util>
933              
934             L<Try::Tiny|Try::Tiny>
935              
936             =head1 INCOMPATIBILITIES
937              
938             none
939              
940             =head1 BUGS AND LIMITATIONS
941              
942             none
943              
944             =head1 SEE ALSO
945              
946             L<map|http://perldoc.perl.org/functions/map.html>
947              
948             L<Data::Visitor|Data::Visitor>
949              
950             L<Hash::Map::Tutorial|Hash::Map::Tutorial>
951              
952             =head1 AUTHOR
953              
954             Steffen Winkler
955              
956             inspired by: Andreas Specht C<< <ACID@cpan.org> >>
957              
958             =head1 LICENSE AND COPYRIGHT
959              
960             Copyright (c) 2012,
961             Steffen Winkler
962             C<< <steffenw at cpan.org> >>.
963             All rights reserved.
964              
965             This module is free software;
966             you can redistribute it and/or modify it
967             under the same terms as Perl itself.