实施' ='方法和method_missing一起使用

时间:2016-05-29 17:58:50

标签: ruby overloading

我有一个模块Settings,如下所示:

module Settings
  extend self

  @_settings = {user: "user1"} #@_seetings would normally be filled with different (dynamic) options
  attr_reader :_settings

  def method_missing(name, *args, &block)
    @_settings.has_key?(name.to_sym) ? @_settings[name.to_sym] :
      raise(NoMethodError, "unknown configuration root #{name}", caller)
  end
end

在我的应用程序中,我可以使用Settings.user来访问选项user

现在我想做这样的事情Settings.user = "some_user"

我试图补充一下:

def method_missing=(name, *args, &block)
  #some code to assign the value
end

不幸的是,这不起作用。 (unknown configuration root user= (NoMethodError))。什么是'权利'这样做的方法?

2 个答案:

答案 0 :(得分:2)

引用不存在的方法的filter方法名称仍会被something=捕获。

您可能希望修改method_missing以查看名称是否以' ='并据此行事。

也就是说,如果您说method_missing,那么您在Settings.method_name 模块上调用方法,而不是包含该模块的实例。

此外,模块不包含状态;这是区别于类的事情之一。此外,您确定要覆盖包含类的Settings方法(或者如果以类'方法为准,则忽略它?)。

您能解释一下为什么要使用模块吗?也许您想要在使用它的类中定义一个类并只包含它的一个实例(组合而不是继承)?

答案 1 :(得分:0)

简短的回答是你不能在Ruby中覆盖=,并且覆盖这些类型的运算符被认为是危险的。有关详细信息,请参阅this answer

然而,这个确切的用例很好地由ruby处理。您有两种选择:

def user= (some_object)
   @_settings = {user: some_object}
end

或者为用户设置Setting的属性并使用attr_accessor

module Settings
  attr_accessor :user
  def new(user)
    @user = user
  end
end

你的attr_reader几乎就在那里,它是attr_accessor的一半而另一半是attr_writer。看看这个其他的SO thread