lib/more/facets/stash.rb in facets-2.8.2 vs lib/more/facets/stash.rb in facets-2.8.3
- old
+ new
@@ -1,66 +1,181 @@
-require 'facets/hash/rekey'
-
-# = Hash
-#
# Stash is just like Hash, except that all keys are
# converted to Strings.
#
-# This is rather fresh code, so is not yet complete.
-# For instnace, it currently does not ensure that default
-# keys are strings when using default_proc.
-#
+# Note this doesn't yet handle default_proc.
+
class Stash < Hash
- def fetch(k)
- super(k.to_s)
+ #
+ def self.[](*hash)
+ s = new
+ super(*hash).each{ |k,v| s[k] = v }
+ s
end
- def store(k, v)
- super(k.to_s, v)
+ #
+ def [](key)
+ super(convert_key(key))
end
- def has_key?(k)
- super(k.to_s)
+ #
+ def []=(key,value)
+ super(convert_key(key), value)
end
- def key?(k)
- super(k.to_s)
+ #
+ def <<(other)
+ case other
+ when Hash
+ super(other.rekey{ |key| convert_key(key) })
+ when Array
+ self[other[0]] = other[1]
+ else
+ raise ArgumentError
+ end
end
- def [](k)
- super(k.to_s)
+ #
+ def fetch(key)
+ super(convert_key(key))
end
- def []=(k,v)
- super(k.to_s, v)
+ #
+ def store(key, value)
+ super(convert_key(key), value)
end
- def <<(other)
- cash other
- when Hash
- super(other.rekey(&:to_s))
- when Array
- self[other[0].to_s] = other[1]
+ #
+ def key?(key)
+ super(convert_key(key))
+ end
+
+ #
+ def has_key?(key)
+ super(convert_key(key))
+ end
+
+ #
+ def include?(key)
+ super(convert_key(key))
+ end
+
+ #
+ def member?(key)
+ super(convert_key(key))
+ end
+
+
+ # Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
+ #
+ # foo = { :name=>'Gavin', :wife=>:Lisa }.to_stash
+ # foo.rekey!{ |k| k.upcase } #=> { "NAME"=>"Gavin", "WIFE"=>:Lisa }
+ # foo.inspect #=> { "NAME"=>"Gavin", "WIFE"=>:Lisa }
+ #
+ def rekey!(*args, &block)
+ # for backward comptability (TODO: DEPRECATE?).
+ block = args.pop.to_sym.to_proc if args.size == 1
+ if args.empty?
+ block = lambda{|k| k} unless block
+ keys.each do |k|
+ nk = block[k]
+ self[nk.to_s]=delete(k) #if nk
+ end
else
- raise ArgumentError
+ raise ArgumentError, "3 for 2" if block
+ to, from = *args
+ self[to] = delete(from) if has_key?(from)
end
+ self
end
+ #
+ def rekey(*args, &block)
+ dup.rekey!(*args, &block)
+ end
+
+ #
+ def delete(key)
+ super(convert_key(key))
+ end
+
+ #
def update(other)
- super(other.rekey(&:to_s))
+ super(other.rekey{ |key| convert_key(key) })
end
+ # Same as #update.
def merge!(other)
- super(other.rekey(&:to_s))
+ super(other.rekey{ |key| convert_key(key) })
end
-
- def replace
- super(other.rekey(&:to_s))
+
+ #
+ def merge(other)
+ super(other.rekey{ |key| convert_key(key) })
end
+ #
+ def replace(other)
+ super(other.rekey{ |key| convert_key(key) })
+ end
+
+ #
def values_at(*keys)
- super(keys.map{|k|k.to_s})
+ super(*keys.map{ |key| convert_key(key) })
+ end
+
+ #
+ def to_hash
+ h = {}
+ each{ |k,v| h[k] = v }
+ h
+ end
+
+ alias_method :to_h, :to_hash
+
+ private
+
+ def convert_key(key)
+ key.to_s
+ end
+
+end
+
+class Hash
+
+ # Convert a Hash to a Stash object.
+ def to_stash
+ Stash[self]
+ end
+
+ # Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
+ #
+ # foo = { :name=>'Gavin', :wife=>:Lisa }
+ # foo.rekey!{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa }
+ # foo.inspect #=> { "name"=>"Gavin", "wife"=>:Lisa }
+ #
+ # This method comes from Ruby Facets.
+
+ def rekey!(*args, &block)
+ # for backward comptability (TODO: DEPRECATE).
+ block = args.pop.to_sym.to_proc if args.size == 1
+ if args.empty?
+ block = lambda{|k| k.to_sym} unless block
+ keys.each do |k|
+ nk = block[k]
+ self[nk]=delete(k) if nk
+ end
+ else
+ raise ArgumentError, "3 for 2" if block
+ to, from = *args
+ self[to] = self.delete(from) if self.has_key?(from)
+ end
+ self
+ end
+
+ # Non-inplace #rekey! method.
+ def rekey(*args, &block)
+ dup.rekey!(*args, &block)
end
end