我可以从ruby REST API调用创建方法吗?

时间:2015-04-14 05:10:33

标签: ruby json rest

我正在为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"]

但是我想知道这是否可以以编程方式为收到的每个键/值完成,而不需要事先知道要返回的键/值

2 个答案:

答案 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类进行子类化。我对猴子补丁感到不太舒服。