BasicObject is very similar to Ruby's own OpenStruct, but it offers some advantages. With OpenStruct, slots with the same name as predefined Object methods cannot be used. With BasicObject, almost any slot can be defined. BasicObject is a subclass of BasicObject to ensure all method slots, except those that are absolutely essential, are open for use.
Unlike a Hash, all BasicObject's keys are symbols and all keys are converted to such using to_sym on the fly.
PUBLIC_METHODS = /(^__|^instance_|^object_|^W|^as$|^send$|^class$|?$)/ protected(*public_instance_methods.select{ |m| m !~ PUBLIC_METHODS })
# File lib/hashery/basicstruct.rb, line 34 def self.[](hash=nil) new(hash) end
Inititalizer for BasicObject is slightly different than that of Hash. It does not take a default parameter, but an initial priming Hash, like OpenStruct. The initializer can still take a default block however. To set the default value use #default!(value).
BasicObject.new(:a=>1).default!(0)
# File lib/hashery/basicstruct.rb, line 45 def initialize(hash=nil, &yld) @table = Hash.new(&yld) if hash hash.each{ |k,v| store(k,v) } end end
# File lib/hashery/basicstruct.rb, line 156 def <<(x) case x when Hash @table.update(x) when Array x.each_slice(2) do |(k,v)| @table[k] = v end end end
Check equality.
# File lib/hashery/basicstruct.rb, line 130 def ==( other ) case other when BasicObject @table == other.as_hash when Hash @table == other else if other.respond_to?(:to_hash) @table == other.to_hash else false end end end
# File lib/hashery/basicstruct.rb, line 173 def [](key) @table[key.to_sym] end
# File lib/hashery/basicstruct.rb, line 168 def []=(key, value) @table[key.to_sym] = value end
NOT SURE ABOUT THIS
# File lib/hashery/basicstruct.rb, line 103 def as_hash @table end
Set the default value.
# File lib/hashery/basicstruct.rb, line 125 def default!(default) @table.default = default end
Iterate over each key-value pair.
# File lib/hashery/basicstruct.rb, line 120 def each(&yld) @table.each(&yld) end
# File lib/hashery/basicstruct.rb, line 146 def eql?( other ) case other when BasicObject @table.eql?(other.as_hash) else false end end
# File lib/hashery/basicstruct.rb, line 53 def initialize_copy(orig) orig.each{ |k,v| store(k,v) } end
Object inspection. TODO: Need to get __class__ and __id__ in hex form.
# File lib/hashery/basicstruct.rb, line 59 def inspect #@table.inspect hexid = __id__ klass = "BasicObject" # __class__ "#<#{klass}:#{hexid} #{@table.inspect}>" end
# File lib/hashery/basicstruct.rb, line 113 def is_a?(klass) return true if klass == Hash # TODO: Is this wise? How to fake a subclass? return true if klass == BasicObject false end
Is a given key defined?
# File lib/hashery/basicstruct.rb, line 108 def key?(key) @table.key?(key.to_sym) end
# File lib/hashery/basicstruct.rb, line 178 def merge!(other) BasicObject.new(@table.merge!(other)) end
Convert to an associative array.
# File lib/hashery/basicstruct.rb, line 67 def to_a @table.to_a end
# File lib/hashery/basicstruct.rb, line 82 def to_basicstruct self end
# File lib/hashery/basicstruct.rb, line 77 def to_hash @table.dup end
Convert to an assignment procedure.
# File lib/hashery/basicstruct.rb, line 87 def to_proc(response=false) hash = @table if response lambda do |o| hash.each do |k,v| o.__send__("#{k}=", v) rescue nil end end else lambda do |o| hash.each{ |k,v| o.__send__("#{k}=", v) } end end end
# File lib/hashery/basicstruct.rb, line 194 def fetch(k, *d, &b) @table.fetch(k.to_sym, *d, &b) end
def protect_slot( key )
(class << self; self; end).class_eval { protected key rescue nil }
end
# File lib/hashery/basicstruct.rb, line 220 def method_missing(sym, *args, &blk) type = sym.to_s[-1,1] key = sym.to_s.sub(/[=?!]$/,'').to_sym case type when '=' store(key, args[0]) when '!' @table.__send__(key, *args, &blk) # if key?(key) # fetch(key) # else # store(key, BasicObject.new) # end when '?' fetch(key) else fetch(key) end end
Generated with the Darkfish Rdoc Generator 2.