我有一个模块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)
)。什么是'权利'这样做的方法?
答案 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