lib/map.rb in map-5.8.0 vs lib/map.rb in map-6.0.0
- old
+ new
@@ -1,8 +1,8 @@
# -*- encoding : utf-8 -*-
class Map < Hash
- Version = '5.8.0' unless defined?(Version)
+ Version = '6.0.0' unless defined?(Version)
Load = Kernel.method(:load) unless defined?(Load)
class << Map
def version
Map::Version
@@ -646,61 +646,63 @@
# support for compound key indexing and depth first iteration
#
def get(*keys)
keys = key_for(keys)
+
if keys.size <= 1
if !self.has_key?(keys.first) && block_given?
return yield
else
return self[keys.first]
end
end
+
keys, key = keys[0..-2], keys[-1]
collection = self
+
keys.each do |k|
- k = alphanumeric_key_for(k)
- if collection_has_key?(collection, k)
- collection = collection[k]
+ if Map.collection_has?(collection, k)
+ collection = Map.collection_key(collection, k)
else
collection = nil
end
+
unless collection.respond_to?('[]')
leaf = collection
return leaf
end
end
- alphanumeric_key = alphanumeric_key_for(key)
- if !collection_has_key?(collection, alphanumeric_key) && block_given?
- yield
+ if !Map.collection_has?(collection, key) && block_given?
+ default_value = yield
else
- collection[alphanumeric_key]
+ Map.collection_key(collection, key)
end
end
def has?(*keys)
keys = key_for(keys)
collection = self
- return collection_has_key?(collection, keys.first) if keys.size <= 1
+
+ return Map.collection_has?(collection, keys.first) if keys.size <= 1
+
keys, key = keys[0..-2], keys[-1]
+
keys.each do |k|
- k = alphanumeric_key_for(k)
- if collection_has_key?(collection, k)
- collection = collection[k]
+ if Map.collection_has?(collection, k)
+ collection = Map.collection_key(collection, k)
else
collection = nil
end
+
return collection unless collection.respond_to?('[]')
end
+
return false unless(collection.is_a?(Hash) or collection.is_a?(Array))
- collection_has_key?(collection, alphanumeric_key_for(key))
- end
- def blank?(*keys)
- return empty? if keys.empty?
- !has?(*keys) or Map.blank?(get(*keys))
+ Map.collection_has?(collection, key)
end
def Map.blank?(value)
return value.blank? if value.respond_to?(:blank?)
@@ -714,19 +716,90 @@
else
value.respond_to?(:empty?) ? value.empty? : !value
end
end
- def collection_has_key?(collection, key)
+ def blank?(*keys)
+ return empty? if keys.empty?
+ !has?(*keys) or Map.blank?(get(*keys))
+ end
+
+ def Map.collection_key(collection, key, &block)
case collection
+ when Array
+ begin
+ key = Integer(key)
+ rescue
+ raise(IndexError, "(#{ collection.inspect })[#{ key.inspect }]")
+ end
+ collection[key]
+
when Hash
- collection.has_key?(key)
+ collection[key]
+
+ else
+ raise(IndexError, "(#{ collection.inspect })[#{ key.inspect }]")
+ end
+ end
+
+ def collection_key(*args, &block)
+ Map.collection_key(*args, &block)
+ end
+
+ def Map.collection_has?(collection, key, &block)
+ has_key =
+ case collection
+ when Array
+ key = (Integer(key) rescue -1)
+ (0...collection.size).include?(key)
+
+ when Hash
+ collection.has_key?(key)
+
+ else
+ raise(IndexError, "(#{ collection.inspect })[#{ key.inspect }]")
+ end
+
+ block.call(key) if(has_key and block)
+
+ has_key
+ end
+
+ def collection_has?(*args, &block)
+ Map.collection_has?(*args, &block)
+ end
+
+ def Map.collection_set(collection, key, value, &block)
+ set_key = false
+
+ case collection
when Array
- (0...collection.size).include?((Integer(key) rescue -1))
+ begin
+ key = Integer(key)
+ rescue
+ raise(IndexError, "(#{ collection.inspect })[#{ key.inspect }]=#{ value.inspect }")
+ end
+ set_key = true
+ collection[key] = value
+
+ when Hash
+ set_key = true
+ collection[key] = value
+
+ else
+ raise(IndexError, "(#{ collection.inspect })[#{ key.inspect }]=#{ value.inspect }")
end
+
+ block.call(key) if(set_key and block)
+
+ [key, value]
end
+ def collection_set(*args, &block)
+ Map.collection_set(*args, &block)
+ end
+
def set(*args)
case
when args.empty?
return []
when args.size == 1 && args.first.is_a?(Hash)
@@ -740,11 +813,11 @@
strategy = hash.map{|key, value| [Array(key), value]}
strategy.each do |key, value|
leaf_for(key, :autovivify => true) do |leaf, k|
- leaf[k] = value
+ Map.collection_set(leaf, k, value)
end
end
self
end
@@ -842,44 +915,28 @@
end
def leaf_for(key, options = {}, &block)
leaf = self
key = Array(key).flatten
- k = alphanumeric_key_for(key.first)
+ k = key.first
key.each_cons(2) do |a, b|
- a, b = alphanumeric_key_for(a), alphanumeric_key_for(b)
+ exists = Map.collection_has?(leaf, a)
- exists = collection_has_key?(leaf, a)
-
case b
when Numeric
if options[:autovivify]
- leaf[a] = [] unless exists
+ Map.collection_set(leaf, a, Array.new) unless exists
end
- case
- when Array, Hash
- nil
- else
- raise(IndexError, "(#{ leaf.inspect })[#{ a.inspect }][#{ b.inspect }]")
- end
-
when String, Symbol
if options[:autovivify]
- leaf[a] = Map.new unless exists
+ Map.collection_set(leaf, a, Map.new) unless exists
end
-
- case
- when Hash
- nil
- else
- raise(IndexError, "(#{ leaf.inspect })[#{ a.inspect }][#{ b.inspect }]")
- end
end
- leaf = leaf[a]
+ leaf = Map.collection_key(leaf, a)
k = b
end
block ? block.call(leaf, k) : [leaf, k]
end
@@ -938,11 +995,14 @@
end
self
end
def Map.alphanumeric_key_for(key)
- return key if Numeric===key
- key.to_s =~ %r/^\d+$/ ? Integer(key) : key
+ return key if key.is_a?(Numeric)
+
+ digity, stringy, digits = %r/^(~)?(\d+)$/iomx.match(key).to_a
+
+ digity ? stringy ? String(digits) : Integer(digits) : key
end
def alphanumeric_key_for(key)
Map.alphanumeric_key_for(key)
end