~tyil/raku-hash-merge

3cf9f5e0c5180d21cce9ec3a2650d6200ac3c2b4 — Patrick Spek 6 years ago da9c10a
Add Hash::Merge::Unit
2 files changed, 85 insertions(+), 23 deletions(-)

M META6.json
A lib/Hash/Merge/Unit.pm6
M META6.json => META6.json +25 -23
@@ 1,25 1,27 @@
{
    "perl": "6",
    "name": "Hash::Merge",
    "version": "0.2.0",
    "auth": "github:scriptkitties",
    "description": "Module to add deep merge functionality to Hashes",
    "license": "Artistic-2.0",
    "depends": [
    ],
    "provides": {
        "Hash::Merge": "lib/Hash/Merge.pm6"
    },
    "authors": [
        "Samantha McVey <samantham@posteo.net>",
        "Patrick Spek <p.spek@tyil.work>"
    ],
    "tags": [
        "hash",
        "utils"
    ],
    "test-depends": [
        "Test::META"
    ],
    "source-url": "https://github.com/scriptkitties/p6-Hash-Merge.git"
  "auth": "github:scriptkitties",
  "authors": [
    "Samantha McVey <samantham@posteo.net>",
    "Patrick Spek <p.spek@tyil.work>"
  ],
  "depends": [
    
  ],
  "description": "Module to add deep merge functionality to Hashes",
  "license": "Artistic-2.0",
  "name": "Hash::Merge",
  "perl": "6",
  "provides": {
    "Hash::Merge": "lib/Hash/Merge.pm6",
    "Hash::Merge::Unit": "lib/Hash/Merge/Unit.pm6"
  },
  "source-url": "https://github.com/scriptkitties/p6-Hash-Merge.git",
  "tags": [
    "hash",
    "utils"
  ],
  "test-depends": [
    "Test::META"
  ],
  "version": "0.2.0"
}

A lib/Hash/Merge/Unit.pm6 => lib/Hash/Merge/Unit.pm6 +60 -0
@@ 0,0 1,60 @@
#! /usr/bin/env false

use v6;

unit module Hash::Merge::Unit;

#| Merge any number of Hashes together.
sub merge-hashes(
    *@hashes, #= Hashes to merge together
    --> Hash
) is export {
    my %merge-into = @hashes.shift;

    # Nothing to do if we only got 1 argument
    return %merge-into unless @hashes.elems;

    for ^@hashes.elems {
        %merge-into = merge-hash(%merge-into, @hashes.shift);
    }

    %merge-into;
}

#| Merge two hashes together.
sub merge-hash(
    %merge-into,   #= The original Hash that should be merged into.
    %merge-source, #= Another Hash to merge into the original Hash.
    Bool:D :$no-append-array = False,
    --> Hash
) is export {
    for %merge-source.keys -> $key {
        if %merge-into{$key}:exists {
            given %merge-source{$key} {
                when Hash {
                    merge-hash(%merge-into{$key}, %merge-source{$key}, :$no-append-array);
                }
                when Positional {
                    %merge-into{$key} = $no-append-array
                    ?? %merge-source{$key}
                    !!
                    do {
                        my @a;
                        @a.push: $_ for %merge-into{$key}.list;
                        @a.push: $_ for %merge-source{$key}.list;
                        @a;
                    }
                }
                default {
                    %merge-into{$key} = %merge-source{$key}
                }
            }
        } else {
            %merge-into{$key} = %merge-source{$key};
        }
    }

    %merge-into;
}

# vim: ft=perl6 ts=4 sw=4 et