Ruby类:使用yaml处理任何未实现的方法

时间:2015-02-13 13:11:15

标签: ruby yaml notimplementedexception

我想创建一个特殊设置类Settings。当用户输入类似Settings.new.method_1.method_2.method_3的内容时,该类应该能够处理这种情况,并将其转换为以下内容:

result = nil
if ConfigurationSettings['method_1'].present? 
  result = ConfigurationSettings['method_1'] 
  if result['method_2'].present?
  result = result['method_2']
  ...
end

return result 

当然,我稍后会更灵活,因此它可以有超过2/3的“方法”。

3 个答案:

答案 0 :(得分:0)

我想这是你面临的问题:

class Settings
 def abc
   puts "abc"
 end
 def xyz
   puts "xyz"
 end
end

s = Settings.new
s.abc
#abc
# => nil
s.xyz
#xyz
# => nil
s.abc.xyz
#abc
#NoMethodError: undefined method `xyz' for nil:NilClass

此处的问题是s.abc正在返回nilxyz将通过nil进行调用。您要实现的目标称为Method Chaining。现在,xyz需要Settings个对象。最简单的方法是:

class Settings2
  def abc
    puts "abc"
    self
  end
  def xyz
    puts "xyz"
    self
  end
end

s2 = Settings2.new
s2.abc.xyz
#abc
#xyz

答案 1 :(得分:0)

method_missing可供您使用,可用于帮助您解决此问题。将此与方法链接相结合,您就可以了。例如:

class Settings
    def method_missing(meth)
        puts "Missing #{meth}"
        self
    end

    def test
        puts "Test"
        self
    end
end

a = Settings.new
a.test
a.test.b
a.b.test

答案 2 :(得分:0)

其他答案的问题是所有方法都返回“self”所以如果你想访问嵌套值...

final_value = Settings.new.method_1.method_2.method_3 

您只需要获取整个设置哈希值。

试试这个......

class Settings
  class SubSettings
    def initialize(sub_setting)
      @sub_setting = sub_setting
    end
    def method_missing(method, *arguments, &block)
      if @sub_setting[method].is_a?(Hash)
        SubSettings.new @sub_setting[method]
      else
        @sub_setting[method]
      end
    end
    def answer
      @sub_setting
    end
  end
  def initialize
    @settings = ConfigurationSettings
  end
  def method_missing(method, *arguments, &block)
    SubSettings.new @settings[method]
  end
end

ConfigurationSettings = {level1a: {level2a: {level3a: "hello", level3b: "goodbye"}, level2b: {level3b: "howdy"}}}

result = Settings.new.level1a.level2a.level3b
p result
=> "goodbye"

这样做是采用初始方法并获取ConfigurationSettings哈希的相关子哈希并将其存储到类SubSettings的新对象中。它应用下一个方法,如果结果是另一个子哈希,它会迭代创建另一个子设置等。它只返回实际结果,当它不再看到哈希时。