lib/key_tree/path.rb in key_tree-0.5.3 vs lib/key_tree/path.rb in key_tree-0.6.0
- old
+ new
@@ -1,18 +1,24 @@
-module KeyTree
+# frozen_string_literal: true
+
+require_relative 'refinements'
+
+module KeyTree # rubocop:disable Style/Documentation
+ using Refinements
+
#
# Representation of the key path to a value in a key tree
#
class Path < Array
#
# KeyTree::Path[+key_or_path+, ...]
#
# Make a new key path from one or more keys or paths
#
- def self.[](*keys_or_paths)
- keys_or_paths.reduce(Path.new) do |result, key_or_path|
- result << Path.new(key_or_path)
+ def self.[](*key_paths)
+ key_paths.reduce(Path.new) do |result, key_path|
+ result << key_path.to_key_path
end
end
#
# KeyTree::Path.new(+key_or_path+)
@@ -22,70 +28,61 @@
#
# Example:
# KeyTree::Path.new("a.b.c")
# => ["a", "b", "c"]
#
- def initialize(key_or_path = [])
- case key_or_path
- when String
- initialize(key_or_path.split('.'))
- when Symbol
- initialize(key_or_path.to_s)
+ def initialize(key_path = nil)
+ case key_path
+ when NilClass
+ nil
when Array
- key_or_path.each { |key| append(key.to_sym) }
+ concat(key_path.map(&:to_sym))
else
- raise ArgumentError, 'key path must be String, Symbol or Array of those'
+ initialize(key_path.to_key_path)
end
end
+ def to_key_path
+ self
+ end
+
def to_s
join('.')
end
def inspect
%("#{self}")
end
def <<(other)
- case other
- when Path
- other.reduce(self) do |result, key|
- result.append(key)
- end
- else
- self << Path[other]
- end
+ concat(other.to_key_path)
end
def +(other)
- dup << other
+ dup.concat(other.to_key_path)
end
- # drop(+prefix+)
+ # Returns a key path without the leading +prefix+
#
- # Returns a key path without the leading prefix
- #
- # drop(+n+)
- #
- # Returns a key path without the first n elements
- #
- def drop(prefix)
- case prefix
- when Path
- return self unless prefix?(other)
- drop(other.length)
- else
- super(prefix)
- end
+ # :call-seq:
+ # Path - other => Path
+ def -(other)
+ other = other.to_key_path
+ raise KeyError unless prefix?(other)
+ super(other.length)
end
# Is +other+ a prefix?
#
+ # :call-seq:
+ # prefix?(other) => boolean
def prefix?(other)
+ other = other.to_key_path
return false if other.length > length
key_enum = each
other.all? { |other_key| key_enum.next == other_key }
end
+ alias === prefix?
# Would +other+ conflict?
#
def conflict?(other)
prefix?(other) || other.prefix?(self) if self != other