Hash-Merge-Simple-0.051/000075500000000000000000000000001171117020300146555ustar00rootroot00000000000000Hash-Merge-Simple-0.051/Changes000064400000000000000000000016361171117020300161560ustar00rootroot00000000000000TODO: - merge => _merge - merge( clone => ... - merge( dclone / deep_clone / storable_clone => ... - merge( [] ) # Transform even-element array into a hash - merge( [], [], ... ) # Merge even-element arrays (at the top level only) 0.051 Tuesday December 07 12:21:04 PST 2010: - Duh, require Exporter. Thanks, EVERYBODY/KENTNL 0.050 Thursday May 13 11:24:29 PDT 2010: - Conversion to Dist::Zilla (Dzpl), losing auto_install 0.04 Saturday February 21 23:22:34 PST 2009: - Addressed bug 41738: https://rt.cpan.org/Ticket/Display.html?id=41738 (thanks Uri) - Updated boilerplate and Makefile.PL - Conversion of repository to git (github) 0.03 Sunday May 04 02:39:59 PDT 2008: - Tweak acknowledgements - Reference Hash::Merge in SEE ALSO 0.02 Wednesday April 23 14:34:59 PDT 2008: - Minor documentation tweak 0.01 Monday April 21 22:12:45 PDT 2008: - Initial release Hash-Merge-Simple-0.051/MANIFEST000064400000000000000000000002121171117020300160010ustar00rootroot00000000000000Changes MANIFEST META.yml Makefile.PL README lib/Hash/Merge/Simple.pm t/00-load.t t/01-basic.t t/9000-bug-41738-merge-with-side-effects.t Hash-Merge-Simple-0.051/META.yml000064400000000000000000000007321171117020300161300ustar00rootroot00000000000000--- abstract: 'Recursively merge two or more hashes, simply' author: - 'Robert Krimen ' build_requires: Test::Most: 0 configure_requires: ExtUtils::MakeMaker: 6.31 dynamic_config: 0 generated_by: 'Dist::Zilla version 4.102345, CPAN::Meta::Converter version 2.102400' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Hash-Merge-Simple requires: Clone: 0 Storable: 0 version: 0.051 Hash-Merge-Simple-0.051/Makefile.PL000064400000000000000000000020461171117020300166310ustar00rootroot00000000000000 use strict; use warnings; use ExtUtils::MakeMaker 6.31; my %WriteMakefileArgs = ( 'ABSTRACT' => 'Recursively merge two or more hashes, simply', 'AUTHOR' => 'Robert Krimen ', 'BUILD_REQUIRES' => { 'Test::Most' => '0' }, 'CONFIGURE_REQUIRES' => { 'ExtUtils::MakeMaker' => '6.31' }, 'DISTNAME' => 'Hash-Merge-Simple', 'EXE_FILES' => [], 'LICENSE' => 'perl', 'NAME' => 'Hash::Merge::Simple', 'PREREQ_PM' => { 'Clone' => '0', 'Storable' => '0' }, 'VERSION' => '0.051', 'test' => { 'TESTS' => 't/*.t' } ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) { my $br = delete $WriteMakefileArgs{BUILD_REQUIRES}; my $pp = $WriteMakefileArgs{PREREQ_PM}; for my $mod ( keys %$br ) { if ( exists $pp->{$mod} ) { $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod}; } else { $pp->{$mod} = $br->{$mod}; } } } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); Hash-Merge-Simple-0.051/README000064400000000000000000000072231171117020300155410ustar00rootroot00000000000000NAME Hash::Merge::Simple - Recursively merge two or more hashes, simply VERSION version 0.051 SYNOPSIS use Hash::Merge::Simple qw/ merge /; my $a = { a => 1 }; my $b = { a => 100, b => 2}; # Merge with righthand hash taking precedence my $c = merge $a, $b; # $c is { a => 100, b => 2 } ... Note: a => 100 has overridden => 1 # Also, merge will take care to recursively merge any subordinate hashes found my $a = { a => 1, c => 3, d => { i => 2 }, r => {} }; my $b = { b => 2, a => 100, d => { l => 4 } }; my $c = merge $a, $b; # $c is { a => 100, b => 2, c => 3, d => { i => 2, l => 4 }, r => {} } # You can also merge more than two hashes at the same time # The precedence increases from left to right (the rightmost has the most precedence) my $everything = merge $this, $that, $mine, $yours, $kitchen_sink, ...; DESCRIPTION Hash::Merge::Simple will recursively merge two or more hashes and return the result as a new hash reference. The merge function will descend and merge hashes that exist under the same node in both the left and right hash, but doesn't attempt to combine arrays, objects, scalars, or anything else. The rightmost hash also takes precedence, replacing whatever was in the left hash if a conflict occurs. This code was pretty much taken straight from Catalyst::Utils, and modified to handle more than 2 hashes at the same time. USAGE Hash::Merge::Simple->merge( , , , ..., ) Hash::Merge::Simple::merge( , , , ..., ) Merge through , with the nth-most (rightmost) hash taking precedence. Returns a new hash reference representing the merge. NOTE: The code does not currently check for cycles, so infinite loops are possible: my $a = {}; $a->{b} = $a; merge $a, $a; NOTE: If you want to avoid giving/receiving side effects with the merged result, use "clone_merge" or "dclone_merge" An example of this problem (thanks Uri): my $left = { a => { b => 2 } } ; my $right = { c => 4 } ; my $result = merge( $left, $right ) ; $left->{a}{b} = 3 ; $left->{a}{d} = 5 ; # $result->{a}{b} == 3 ! # $result->{a}{d} == 5 ! Hash::Merge::Simple->clone_merge( , , , ..., ) Hash::Merge::Simple::clone_merge( , , , ..., ) Perform a merge, clone the merge, and return the result This is useful in cases where you need to ensure that the result can be tweaked without fear of giving/receiving any side effects This method will use Clone to do the cloning Hash::Merge::Simple->dclone_merge( , , , ..., ) Hash::Merge::Simple::dclone_merge( , , , ..., ) Perform a merge, clone the merge, and return the result This is useful in cases where you need to ensure that the result can be tweaked without fear of giving/receiving any side effects This method will use Storable (dclone) to do the cloning SEE ALSO Hash::Merge Catalyst::Utils Clone Storable ACKNOWLEDGEMENTS This code was pretty much taken directly from Catalyst::Utils: Sebastian Riedel "sri@cpan.org" Yuval Kogman "nothingmuch@woobling.org" AUTHOR Robert Krimen COPYRIGHT AND LICENSE This software is copyright (c) 2010 by Robert Krimen. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Hash-Merge-Simple-0.051/lib/000075500000000000000000000000001171117020300154235ustar00rootroot00000000000000Hash-Merge-Simple-0.051/lib/Hash/000075500000000000000000000000001171117020300163065ustar00rootroot00000000000000Hash-Merge-Simple-0.051/lib/Hash/Merge/000075500000000000000000000000001171117020300173455ustar00rootroot00000000000000Hash-Merge-Simple-0.051/lib/Hash/Merge/Simple.pm000064400000000000000000000113311171117020300211330ustar00rootroot00000000000000package Hash::Merge::Simple; BEGIN { $Hash::Merge::Simple::VERSION = '0.051'; } # ABSTRACT: Recursively merge two or more hashes, simply use warnings; use strict; use vars qw/ @ISA @EXPORT_OK /; require Exporter; @ISA = qw/ Exporter /; @EXPORT_OK = qw/ merge clone_merge dclone_merge /; # This was stoled from Catalyst::Utils... thanks guys! sub merge (@); sub merge (@) { shift unless ref $_[0]; # Take care of the case we're called like Hash::Merge::Simple->merge(...) my ($left, @right) = @_; return $left unless @right; return merge($left, merge(@right)) if @right > 1; my ($right) = @right; my %merge = %$left; for my $key (keys %$right) { my ($hr, $hl) = map { ref $_->{$key} eq 'HASH' } $right, $left; if ($hr and $hl){ $merge{$key} = merge($left->{$key}, $right->{$key}); } else { $merge{$key} = $right->{$key}; } } return \%merge; } sub clone_merge { require Clone; my $result = merge @_; return Clone::clone( $result ); } sub dclone_merge { require Storable; my $result = merge @_; return Storable::dclone( $result ); } 1; __END__ =pod =head1 NAME Hash::Merge::Simple - Recursively merge two or more hashes, simply =head1 VERSION version 0.051 =head1 SYNOPSIS use Hash::Merge::Simple qw/ merge /; my $a = { a => 1 }; my $b = { a => 100, b => 2}; # Merge with righthand hash taking precedence my $c = merge $a, $b; # $c is { a => 100, b => 2 } ... Note: a => 100 has overridden => 1 # Also, merge will take care to recursively merge any subordinate hashes found my $a = { a => 1, c => 3, d => { i => 2 }, r => {} }; my $b = { b => 2, a => 100, d => { l => 4 } }; my $c = merge $a, $b; # $c is { a => 100, b => 2, c => 3, d => { i => 2, l => 4 }, r => {} } # You can also merge more than two hashes at the same time # The precedence increases from left to right (the rightmost has the most precedence) my $everything = merge $this, $that, $mine, $yours, $kitchen_sink, ...; =head1 DESCRIPTION Hash::Merge::Simple will recursively merge two or more hashes and return the result as a new hash reference. The merge function will descend and merge hashes that exist under the same node in both the left and right hash, but doesn't attempt to combine arrays, objects, scalars, or anything else. The rightmost hash also takes precedence, replacing whatever was in the left hash if a conflict occurs. This code was pretty much taken straight from L, and modified to handle more than 2 hashes at the same time. =head1 USAGE =head2 Hash::Merge::Simple->merge( , , , ..., ) =head2 Hash::Merge::Simple::merge( , , , ..., ) Merge through , with the nth-most (rightmost) hash taking precedence. Returns a new hash reference representing the merge. NOTE: The code does not currently check for cycles, so infinite loops are possible: my $a = {}; $a->{b} = $a; merge $a, $a; NOTE: If you want to avoid giving/receiving side effects with the merged result, use C or C An example of this problem (thanks Uri): my $left = { a => { b => 2 } } ; my $right = { c => 4 } ; my $result = merge( $left, $right ) ; $left->{a}{b} = 3 ; $left->{a}{d} = 5 ; # $result->{a}{b} == 3 ! # $result->{a}{d} == 5 ! =head2 Hash::Merge::Simple->clone_merge( , , , ..., ) =head2 Hash::Merge::Simple::clone_merge( , , , ..., ) Perform a merge, clone the merge, and return the result This is useful in cases where you need to ensure that the result can be tweaked without fear of giving/receiving any side effects This method will use L to do the cloning =head2 Hash::Merge::Simple->dclone_merge( , , , ..., ) =head2 Hash::Merge::Simple::dclone_merge( , , , ..., ) Perform a merge, clone the merge, and return the result This is useful in cases where you need to ensure that the result can be tweaked without fear of giving/receiving any side effects This method will use L (dclone) to do the cloning =head1 SEE ALSO L L L L =head1 ACKNOWLEDGEMENTS This code was pretty much taken directly from L: Sebastian Riedel C Yuval Kogman C =head1 AUTHOR Robert Krimen =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2010 by Robert Krimen. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Hash-Merge-Simple-0.051/t/000075500000000000000000000000001171117020300151205ustar00rootroot00000000000000Hash-Merge-Simple-0.051/t/00-load.t000064400000000000000000000002471171117020300164440ustar00rootroot00000000000000#!perl -T use Test::More tests => 1; BEGIN { use_ok( 'Hash::Merge::Simple' ); } diag( "Testing Hash::Merge::Simple $Hash::Merge::Simple::VERSION, Perl $], $^X" ); Hash-Merge-Simple-0.051/t/01-basic.t000064400000000000000000000020051171117020300166010ustar00rootroot00000000000000use Test::More; use Test::Deep; plan qw/no_plan/; use Hash::Merge::Simple qw/merge/; { my $a = { a => 1 }; my $b = { a => 100, b => 2}; my $c = merge $a, $b; ok($c); cmp_deeply($c, { a => 100, b => 2 }); } { my $a = { a => 1, c => 3, d => { i => 2 }, r => {} }; my $b = { b => 2, a => 100, d => { l => 4 } }; my $c = merge $a, $b; ok($c); cmp_deeply($c, { a => 100, b => 2, c => 3, d => { i => 2, l => 4 }, r => {} }); } { cmp_deeply(merge({ a => 1 }, { a => 2 }, { a => 3 }, { a => 4 }, { a => 5 }), { a => 5 }); cmp_deeply(merge({ a => 1, b => [] }, { a => 2 }, { a => 3 }, { a => 4 }, { a => 5 }), { a => 5, b => [] }); cmp_deeply(merge({ a => 1, b => [ 3 ] }, { a => 2 }, { a => 3 }, { a => 4, b => [ 8 ] }, { a => 5 }), { a => 5, b => [ 8 ] }); cmp_deeply(merge({ a => 1 }, { b => 2 }, { c => 3 }, { d => 4 }, { e => 5 }), { qw/a 1 b 2 c 3 d 4 e 5/ }); } if (0) { exit; # Infinity-ty-ty-ty-ty my $a = {}; $a->{b} = $a; merge $a, $a; } Hash-Merge-Simple-0.051/t/9000-bug-41738-merge-with-side-effects.t000064400000000000000000000023141171117020300235410ustar00rootroot00000000000000use strict; use warnings; use Test::Most; use Test::Deep; plan qw/no_plan/; #use Data::Dump qw/dump/; #print dump($left), "\n"; #print dump($merged), "\n"; use Hash::Merge::Simple qw/merge clone_merge dclone_merge/; my ($left, $right, $result); SKIP: { eval "require Clone;" or skip "Clone required for this test"; $left = { foo => { bar => 2 } }; $right = { baz => 4 }; $result = clone_merge( $left, $right ); $left->{foo}{bar} = 3 ; $left->{foo}{aaa} = 5 ; cmp_deeply $left, { foo => { bar => 3, aaa => 5 } }; cmp_deeply $result, { foo => { bar => 2 }, baz => 4 }; } SKIP: { eval "require Storable;" or skip "Storable required for this test"; $left = { foo => { bar => 2 } }; $right = { baz => 4 }; $result = dclone_merge( $left, $right ); $left->{foo}{bar} = 3 ; $left->{foo}{aaa} = 5 ; cmp_deeply $left, { foo => { bar => 3, aaa => 5 } }; cmp_deeply $result, { foo => { bar => 2 }, baz => 4 }; } $left = { foo => { bar => 2 } }; $right = { baz => 4 }; $result = merge( $left, $right ); $left->{foo}{bar} = 3 ; $left->{foo}{aaa} = 5 ; cmp_deeply $left, { foo => { bar => 3, aaa => 5 } }; cmp_deeply $result, { foo => { aaa => 5, bar => 3 }, baz => 4 };