Ruby - 动态定义类级变量

时间:2015-02-20 00:49:06

标签: ruby oop

我是ruby的新手,想知道这是否可行。假设我有一个包含不同块的文件,如

fruits[tomato=1,orange=2]
greens[peas=2,potato=3]

我已经解析了这个文件并将其存储到像这样的哈希

{“fruits”=> {“tomato”=>“1”,“orange”=>“2”},“greens”=> {“potato”=>“3”,“豌豆“=>”2“}}

而且我也知道如何访问哈希的不同部分。但是假设想要做到这样的话

fruits.tomato  # 1
fruits.orange  # 2
(Like an object with tomato and orange being its variables)

这里的问题是假设我不知道该文件是否包含水果和绿色,它可能包含一个名为肉的不同组。我知道这个动态问题可以解决,如果我将所有内容插入哈希,密钥作为组名称,值将是另一个哈希。但是这可以通过我上面提供的fruit.tomato或fruits.orange的例子来完成(可能是通过在类中声明它但我不确定如何动态地在ruby中添加类变量或者如果我甚至可能因为我是新的语言)。

2 个答案:

答案 0 :(得分:1)

我花了很多时间制作一个这样的程序,以帮助加快API的开发。我最终写了一个宝石来对原始JSON进行客体化(无耻的插件:ClassyJSON)。

那就是说,我认为你的用例对于OpenStruct来说是一个很好的用例。我将我的代码仅限于您的示例和您想要的结果,但这可能是它的样子:

require 'ostruct'

hash = {"fruits"=>{"tomato"=>"1", "orange"=>"2"}, "greens"=>{"potato"=>"3", "peas"=>"2"}}
structs = []

hash.each do |k, v|
  if v.is_a? Hash
    obj = OpenStruct.new({k => OpenStruct.new(v)})
  end
  structs << obj
end

在这里,我们构建了许多OpenStruct对象,并可以按照您的描述访问它们的值:

[1] pry(main)> structs
=> [#<OpenStruct fruits=#<OpenStruct tomato="1", orange="2">>, #<OpenStruct greens=#<OpenStruct potato="3", peas="2">>]
[2] pry(main)> structs.first
=> #<OpenStruct fruits=#<OpenStruct tomato="1", orange="2">>
[3] pry(main)> structs.first.fruits
=> #<OpenStruct tomato="1", orange="2">
[4] pry(main)> structs.first.fruits.tomato
=> "1"

答案 1 :(得分:0)

  def add_accessor_method(name, ref)
    define_singleton_method name do
     return ref
    end
  end

我找到了这个解决方案,它将在解析文件本身时为我创建一个访问器方法。所以我以后不必使用OpenStruct将我的哈希转换为具有不同访问器方法的对象。 (我确信OpenStruct正在做这件事)

相关问题