如何将哈希键转换为方法名称?

Sre*_*raj 48 ruby

这是我的哈希:

tempData = {"a" => 100, "here" => 200, "c" => "hello"}
Run Code Online (Sandbox Code Playgroud)

我需要访问哈希键作为一种方法,如:

tempData.a #100
tempData.here # 200
Run Code Online (Sandbox Code Playgroud)

Mic*_*ohl 91

您可以在OpenStruct中包装哈希:

require 'ostruct'
tempData = {"a" => 100, "here" => 200, "c" => "hello"}
os = OpenStruct.new tempData
os.a #=> 100
os.here #=> 200
Run Code Online (Sandbox Code Playgroud)

如果你真的想要,你也可以修补Hash课程,但我建议反对:

class Hash
  def method_missing(m, *args, &blk)
    fetch(m) { fetch(m.to_s) { super } }
  end
end

tempData = {"a" => 100, "here" => 200, "c" => "hello"}
tempData.a #=> 100
Run Code Online (Sandbox Code Playgroud)

更新:在我的个人扩展库中,我添加了一个Hash#to_ostruct方法.这将递归地将哈希转换为OpenStruct包含所有嵌套哈希的哈希.


Eng*_*mon 11

还有另一种方法可以做到这一点.

JSON.parse(tempData.to_json, object_class: OpenStruct)

这会给对象 #<OpenStruct a=100, here=200, c="hello">

这样嵌套hash也会转换为OpenStruct Object

tempData = {a: { b: { c: 3}}, foo: 200, msg: 'test msg'}
obj = JSON.parse(tempData.to_json, object_class: OpenStruct)
Run Code Online (Sandbox Code Playgroud)

现在我们可以打电话了

obj.a.b.c # 3
obj.foo # 200
obj.msg # 'test msg'
Run Code Online (Sandbox Code Playgroud)

希望这会对某人有所帮助.


aku*_*uhn 6

或者,如果它只是一个小脚本,那么扩展Hash自己可能会更方便

class Hash
  def method_missing sym,*
    fetch(sym){fetch(sym.to_s){super}}
  end
end
Run Code Online (Sandbox Code Playgroud)

method_missing是一个神奇的方法,只要您的代码尝试调用不存在的方法,就会调用该方法.Ruby将在运行时拦截失败的调用,让你处理它,这样你的程序就可以优雅地恢复.上面的实现尝试使用方法名称作为符号访问哈希,使用方法名称作为字符串,并最终失败,Ruby的内置方法丢失错误.

注意更复杂的脚本,添加此行为可能会破坏其他第三方gem,您可以使用模块并扩展每个实例

module H
  def method_missing sym,*
    fetch(sym){fetch(sym.to_s){super}}
  end
end

the = { answer: 42 }
the.extend(H)
the.answer # => 42
Run Code Online (Sandbox Code Playgroud)

为了更方便,您甚至可以将模块传播到嵌套的哈希

module H
  def method_missing sym,*
    r = fetch(sym){fetch(sym.to_s){super}}
    Hash === r ? r.extend(H) : r
  end
end 

the = { answer: { is: 42 } }
the.extend(H)
the.answer.is # => 42
Run Code Online (Sandbox Code Playgroud)