File Coverage

blib/lib/Hash/Util/Merge.pm
Criterion Covered Total %
statement 46 46 100.0
branch 1 2 50.0
condition 2 2 100.0
subroutine 10 10 100.0
pod 1 1 100.0
total 60 61 98.3


line stmt bran cond sub pod time code
1             package Hash::Util::Merge;
2              
3 1     1   164568 use v5.14;
  1         3  
4 1     1   8 use warnings;
  1         2  
  1         104  
5              
6 1     1   9 use Exporter 5.57 ();
  1         20  
  1         36  
7 1     1   7 use List::Util 1.45 ();
  1         15  
  1         38  
8 1     1   611 use Sub::Util 1.45 ();
  1         371  
  1         57  
9              
10             our $VERSION = 'v0.3.0';
11              
12             # ABSTRACT: utility functions for merging hashes
13              
14              
15             our @EXPORT_OK = qw/ mergemap /;
16              
17             sub import {
18              
19             # This borrows a technique from List::Util that exports symbols $a
20             # and $b to the callers namespace, so that function arguments can
21             # simply use $a and $b, akin to how function arguments for sort
22             # works.
23              
24 1     1   33 my $pkg = caller;
25 1     1   4 no strict 'refs'; ## no critic (ProhibitNoStrict)
  1         2  
  1         135  
26 1         2 ${"${pkg}::a"} = ${"${pkg}::a"};
  1         3  
  1         7  
27 1         2 ${"${pkg}::b"} = ${"${pkg}::b"};
  1         3  
  1         3  
28 1         2168 goto &Exporter::import;
29             }
30              
31              
32             sub mergemap {
33              
34 9     9 1 176535 my $pkg = caller;
35 1     1   5 no strict 'refs'; ## no critic (ProhibitNoStrict)
  1         1  
  1         214  
36 9         13 my $glob_a = \ *{"${pkg}::a"};
  9         24  
37 9         10 my $glob_b = \ *{"${pkg}::b"};
  9         14  
38              
39 9         10 my $f = shift;
40 9   100     24 my $x = shift // { };
41              
42 9         14 while (@_) {
43              
44 10         10 my $y = shift;
45              
46 10         11 my %r;
47 10         38 for my $k ( List::Util::uniqstr( keys %$x, keys %$y ) ) {
48 20 50       51 next if exists $r{$k};
49 20         28 local *$glob_a = \$x->{$k};
50 20         21 local *$glob_b = \$y->{$k};
51 20         28 $r{$k} = $f->();
52             }
53              
54 10         49 $x = \%r;
55              
56             }
57              
58 9         13 return $x;
59             }
60              
61             BEGIN {
62 1     1   54 Sub::Util::set_prototype '&@' => \&mergemap;
63             }
64              
65              
66             1;
67              
68             __END__