class FlexHash
Like a combination of HashWithIndifferentAccess, OpenStruct, plus it takes an integer and tries looking it up positionally. (bleh, like php’s but a little more buggy. I know I know- but it’s for a very specific purpose).
Mostly cribbed from rubinius’s ostruct: github.com/rubysl/rubysl-ostruct/blob/2.0/lib/rubysl/ostruct/ostruct.rb with just the [] access function changed and method_missing
changed so it delegates unfound things to the underlying table.
Public Class Methods
[](*arr_const)
click to toggle source
# File lib/flexhash.rb, line 10 def self.[](*arr_const) self.new(arr_const.flatten) end
new(constructor=nil)
click to toggle source
# File lib/flexhash.rb, line 14 def initialize(constructor=nil) @table = {} if constructor.respond_to?(:each_pair) constructor.each_pair{|k,v| self[k.to_sym] = v } elsif constructor.respond_to?(:each_slice) constructor.each_slice(2){|k,v| self[k.to_sym] = v } elsif constructor != nil raise ArgumentError, "cannot initialize flexhash with #{constructor}", caller(3) end end
Public Instance Methods
<<(kv)
click to toggle source
# File lib/flexhash.rb, line 104 def <<(kv) name, value = kv self[name] = value end
==(other)
click to toggle source
# File lib/flexhash.rb, line 143 def ==(other) return false unless other.kind_of?(OpenStruct) @table == other.table end
[](name)
click to toggle source
# File lib/flexhash.rb, line 88 def [](name) if Integer === name @table[name] || @table[@table.keys[name]] else res = @table[name] || @table[name.try(:to_sym)] return res if res res = @table.select{|k,v| name === k} return res.values[0] if res.size == 1 res end end
[]=(name, value)
click to toggle source
# File lib/flexhash.rb, line 100 def []=(name, value) modifiable[new_flexhash_member(name)] = value end
delete_field(name)
click to toggle source
# File lib/flexhash.rb, line 109 def delete_field(name) sym = name.to_sym singleton_class.__send__(:remove_method, sym, "#{name}=") @table.delete sym end
each_pair() { |p| ... }
click to toggle source
# File lib/flexhash.rb, line 35 def each_pair return to_enum __method__ unless block_given? @table.each_pair { |p| yield p } end
eql?(other)
click to toggle source
# File lib/flexhash.rb, line 148 def eql?(other) return false unless other.kind_of?(OpenStruct) @table.eql?(other.table) end
hash()
click to toggle source
# File lib/flexhash.rb, line 153 def hash @table.hash end
initialize_copy(orig)
click to toggle source
Calls superclass method
# File lib/flexhash.rb, line 25 def initialize_copy(orig) super @table = @table.dup @table.each_key { |key| new_flexhash_member(key) } end
inspect()
click to toggle source
# File lib/flexhash.rb, line 117 def inspect str = "#<#{self.class}" ids = (Thread.current[InspectKey] ||= []) if ids.include?(object_id) return str << ' ...>' end ids << object_id begin first = true for k,v in @table str << "," unless first first = false str << " #{k}=#{v.inspect}" end return str << '>' ensure ids.pop end end
Also aliased as: to_s
marshal_dump()
click to toggle source
# File lib/flexhash.rb, line 40 def marshal_dump @table end
marshal_load(x)
click to toggle source
# File lib/flexhash.rb, line 44 def marshal_load(x) @table = x @table.each_key{|key| new_flexhash_member(key)} end
method_missing(mid, *args, &block)
click to toggle source
# File lib/flexhash.rb, line 69 def method_missing(mid, *args, &block) mname = mid.id2name len = args.length if mname.chomp!('=') if len != 1 raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1) end modifiable[new_flexhash_member(mname)] = args[0] elsif len == 0 res = @table[mid] || @table.send(mid, *args, &block) res = FlexHash.new(res) if res.instance_of? Hash res else res = @table.send(mid, *args, &block) res = FlexHash.new(res) if res.instance_of? Hash res end end
to_h()
click to toggle source
# File lib/flexhash.rb, line 31 def to_h @table.dup end
Protected Instance Methods
modifiable()
click to toggle source
# File lib/flexhash.rb, line 49 def modifiable begin @modifiable = true rescue raise TypeError, "can't modify frozen #{self.class}", caller(3) end @table end
new_flexhash_member(name)
click to toggle source
# File lib/flexhash.rb, line 59 def new_flexhash_member(name) name = name.to_sym unless respond_to?(name) define_singleton_method(name) { @table[name] } define_singleton_method("#{name}=") { |x| modifiable[name] = x } end name end