我正在为REST API创建一个客户端,它返回JSON,如下所示:
2.1.5 :006 > system = api.system
=> {"DatabaseVersion"=>5, "Name"=>"Orthanc", "Version"=>"0.8.6"}
我想知道是否有办法将这些JSON密钥转换为方法,所以我可以调用类似
的方法version = api.system.version
并获得该JSON密钥的值:
=> "0.8.6"
显然,我可以将每个JSON项密钥硬编码为客户端中的方法,并使用以下内容检索特定密钥的值:
api.system["Version"]
但是我想知道这是否可以以编程方式为收到的每个键/值完成,而不需要事先知道要返回的键/值
答案 0 :(得分:1)
OpenStruct
来救援:
▶ os = OpenStruct.new({
▷ "DatabaseVersion"=>5,
▷ "Name"=>"Orthanc",
▷ "Version"=>"0.8.6"
▷ })
▶ os.DatabaseVersion
#⇒ 5
答案 1 :(得分:0)
修改强>:
正如@mudasobwa指出的那样,已经有一个标准的实现,一个使用method_missing
的类和一个内部Hash对象...
显然,这种行为受到许多人的喜爱,并且发现它是通往标准库的方式。
请参阅OpenStruct上的文档。
记得要求实施使用: 要求'ostruct'
原帖:
我认为您可能正在寻找基于method_missing
的解决方案。
可以对Hash类进行修补,以获得模仿你想要的行为。
这是一个快速的脏补丁:
class Hash
def method_missing(name, *args, &block)
# getter for symbole
return self[name] if self.has_key? name
# getter for String
return self[name.to_s] if self.has_key? name.to_s
# setter for adding or editing hash keys,
# using the shortcut hash.key = value.
if name.to_s[-1] == '=' && name.to_s.length > 1
self.[]=(name.to_s[0..-2], *args)
self.[]=(name.to_s[0..-2].to_sym, *args)
return *args
end
# nothing happened? move it up the chain for default behavior.
# (assumes Hash doesn't handle missing methods).
super
end
end
这将表现得像一个'即时'吸气器和安装器。请注意,getter仅适用于现有属性,并且不支持该数字(仅限字符串和符号)。
另请注意,符号和字符串将统一 - 如果使用这些getter / setter,则无法使用符号和字符串表示不同的值。此外,符号将具有优先权。
就个人而言,我可能会放弃这样的方便解决方案或选择对Hash类进行子类化。我对猴子补丁感到不太舒服。