Sha256: f1557030ac68e73bc6114b4197688d2d6a1811f1eb06b4417a160d58713c7322

Contents?: true

Size: 1.81 KB

Versions: 6

Compression:

Stored size: 1.81 KB

Contents

require 'key_tree/path'
require 'key_tree/meta_data'
module KeyTree
  # A tree of key-value lookup tables (hashes)
  class Tree < Hash
    include MetaData
    #
    # KeyTree::Tree.new(+hash+)
    #
    # Initialize a new KeyTree from nested Hash:es
    #
    def self.[](hash = {})
      keytree = Tree.new
      hash.each do |key, value|
        keytree[key] = value
      end
      keytree
    end

    def [](key_or_path)
      super(Path[key_or_path])
    end

    def fetch(key_or_path, *args, &proc)
      super(Path[key_or_path], *args, &proc)
    end

    def values_at(*keys)
      super(keys.map { |key_or_path| Path[key_or_path] })
    end

    def []=(key_or_path, new_value)
      path = Path[key_or_path]

      delete_if { |key, _| path.conflict?(key) }

      case new_value
      when Hash
        new_value.each { |suffix, value| super(path + suffix, value) }
      else
        super(path, new_value)
      end
    end

    def key?(key_or_path)
      super(Path[key_or_path])
    end

    def prefix?(key_or_path)
      keys.any? { |key| key.prefix?(Path[key_or_path]) }
    end

    def conflict?(key_or_path)
      keys.any? { |key| key.conflict?(Path[key_or_path]) }
    end

    # All trees are created equal. Forests are always larger than trees.
    #
    def <=>(other)
      case other
      when Forest
        -1
      when Tree
        0
      else
        raise ArgumentError, 'only trees and forests are comparable'
      end
    end

    # The merging of trees needs some extra consideration; due to the
    # nature of key paths, prefix conflicts must be deleted
    #
    def merge!(other)
      other = Tree[other] unless other.is_a?(Tree)
      delete_if { |key, _| other.conflict?(key) }
      super
    end
    alias << merge!

    def merge(other)
      dup.merge!(other)
    end
    alias + merge
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
key_tree-0.4.2 lib/key_tree/tree.rb
key_tree-0.4.1 lib/key_tree/tree.rb
key_tree-0.4.0 lib/key_tree/tree.rb
key_tree-0.3.2 lib/key_tree/tree.rb
key_tree-0.3.1 lib/key_tree/tree.rb
key_tree-0.3.0 lib/key_tree/tree.rb