Ruby使用点符号访问电池

时间:2015-10-02 21:08:15

标签: ruby

我试图构建一个基本上用作存储值/嵌套值的数据结构的类。我希望有两种方法getset,它们接受一个用于递归设置或获取变量的点标记路径。

例如:

bag = ParamBag.new
bag.get('foo.bar') # => nil
bag.set('foo.bar', 'baz')
bag.get('foo.bar') # => 'baz'

如果值不存在,get方法也可以采用默认返回值:

bag.get('foo.baz', false) # => false

我还可以使用哈希初始化新的ParamBag

我如何在Ruby中管理它?我已经用其他语言完成了这个,但是为了设置一个递归路径,我会通过引用获取值,但我不确定我是如何在Ruby中完成的。

1 个答案:

答案 0 :(得分:3)

这是一项有趣的练习,但仍然属于"你可能不应该这样做"类别。

要完成您想要的操作,可以稍微修改一下OpenStruct。

class ParamBag < OpenStruct
  def method_missing(name, *args, &block)
    if super.nil?
      modifiable[new_ostruct_member(name)] = ParamBag.new
    end    
  end
end

这个类允许你将许多方法调用链接在一起,并设置任意数量的参数。

使用Ruby 2.2.1进行测试

2.2.1 :023 > p = ParamBag.new
 => #<ParamBag> 
2.2.1 :024 > p.foo
 => #<ParamBag> 
2.2.1 :025 > p.foo.bar
 => #<ParamBag> 
2.2.1 :026 > p.foo.bar = {}
 => {} 
2.2.1 :027 > p.foo.bar
 => {} 
2.2.1 :028 > p.foo.bar = 'abc'
 => "abc" 

基本上,请取消getset方法并像平常一样调用方法。

我不建议你实际这样做,我建议你单独使用OpenStruct来获得一些灵活性而不会太疯狂。如果你发现自己需要连接大量的方法并让它们永远不会失败,那么可能会倒退一步并且问一下这是解决这个问题的正确方法吗?&#34;。如果对这个问题的回答是肯定的,那么ParamBag可能就是完美的。