Pergunta

For academic reasons, I'd like to make an instance of Ruby class act like a hash.

GOALS

  1. Initialize MyClass instance with a hash # success
  2. Request values from instance of myClass, like a hash # success
  3. Then set properties as a hash # fail

Although some discussion exists, I tried what's out there (1, 2) with no success. Let me know what I'm doing wrong. Thanks!

class MyClass
  attr_accessor :my_hash

  def initialize(hash={})
    @my_hash = hash
  end

  def [](key)
    my_hash[key]
  end

  def set_prop(key, value)
    myhash[key] = value
  end

end

test = myClass.new({:a => 3})     #=> #<MyClass:0x007f96ca943898 @my_hash={:a=>3}>
test[:a]                          #=> 3 
test[:b] = 4                      #=> NameError: undefined local variable or method `myhash' for #<MyClass:0x007f96ca9d0ef0 @my_hash={:a=>3}>
Foi útil?

Solução

You declared set_prop, but you're using []= in tests. Did you mean to get this?

class MyClass
  attr_accessor :my_hash

  def initialize(hash={})
    @my_hash = hash
  end

  def [](key)
    my_hash[key]
  end

  def []=(key, value)
    my_hash[key] = value
  end

end

test = MyClass.new({:a => 3})     # success
test[:a]                          # success
test[:b] = 4                      # success

test.my_hash # => {:a=>3, :b=>4}

Outras dicas

module HashizeModel
    def [](key)
        sym_key = to_sym_key(key)
        self.instance_variable_get(sym_key)
    end

    def []=(key, value)
        sym_key = to_sym_key(key)
        self.instance_variable_set(sym_key, value)
    end

    private

    def to_sym_key(key)
        if key.is_a? Symbol
            return ('@'+key.to_s).to_sym
        else
            return ('@'+key.to_s.delete('@')).to_sym
        end
    end

end

You should write it as test = MyClass.new({:a => 3}) and the below code should work.

class MyClass
  attr_accessor :my_hash

  def initialize(hash={})
    @my_hash = hash
  end

  def [](key)
    @my_hash[key]
  end
  def []=(key,val)
    @my_hash[key]=val
  end
  def set_prop(key, value)
    @myhash[key] = value
  end

end

test = MyClass.new({:a => 3})
test[:a]                          
test[:b]= 4 
test.my_hash # => {:a=>3, :b=>4}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top