Sha256: 2a498ea52c57acd3054b69388637ea0520a2909757d7c8d93734ea4dcb475929

Contents?: true

Size: 1.95 KB

Versions: 1

Compression:

Stored size: 1.95 KB

Contents

class Mostash < OpenStruct
  def initialize(init={})
    super({})
    @initial_hash = init
    __init__ init
  end

  def new_ostruct_member(name)
    name = name.to_sym
    unless self.respond_to?(name)
      super
      eigenclass.class_eval do
        remove_method("#{name}") if self.respond_to?(name)
        define_method("#{name}=") { |x| modifiable[name] = __adjusted_value__ x }
      end
    end
    name
  end

  def method_missing(method_name, *args, &block)
    #dbg "#{method_name} was sent #{args.inspect}, and block #{block.inspect}"
    if @table.respond_to? method_name
      @table.send method_name, *args, &block
    elsif __is_setter__( method_name )
      super method_name, __adjusted_value__( args.first )
    else
      super || @initial_hash.send(:[], method_name, *args, &block)
    end
  end

  def []=(key, value)
    self.send "#{key.to_s}=", __adjusted_value__(value)
  end

  def [](key)
    self.send "#{key.to_s}"
  end

  def merge(new_hash)
    new_mo = @table.merge( new_hash ) do |key, oldval, newval|
      if oldval.class == Mostash
        oldval.merge newval
      else
        newval
      end
    end
    Mostash.new( new_mo )
  end

  #TODO: HACK!!!!!
  def merge!(new_hash)
    @table = self.merge( new_hash ).instance_variable_get( '@table' )
    self
  end

  def to_hash
    hash = {}
    @table.each_pair do |key, value|
      hash[key] = if value.class == Mostash
                    value.to_hash
                  else
                    value
                  end
    end
    hash
  end

  private

  def __init__(hash)
    hash.each_pair do |key, value|
      self.send "#{key.to_s}=", __adjusted_value__( value )
    end
  end

  def __adjusted_value__(value)
    case value
    when Hash then Mostash.new( value )
    when Array then value.map{ |v| __adjusted_value__( v ) }
    else value
    end
  end

  def __is_setter__(method_name)
    method_name.to_s =~ /=$/
  end
 
  def eigenclass
    class << self
      self
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
mostash-0.0.5 lib/mostash/mostash.rb