在Mixins中初始化实例变量 [英] Initializing instance variables in Mixins
问题描述
在打算用作Mixin的模块中,是否有任何干净的方法来初始化实例变量?例如,我有以下内容:
Is there any clean way to initialize instance variables in a Module intended to be used as Mixin? For example, I have the following:
module Example
def on(...)
@handlers ||= {}
# do something with @handlers
end
def all(...)
@all_handlers ||= []
# do something with @all_handlers
end
def unhandled(...)
@unhandled ||= []
# do something with unhandled
end
def do_something(..)
@handlers ||= {}
@unhandled ||= []
@all_handlers ||= []
# potentially do something with any of the 3 above
end
end
请注意,我必须一次又一次地检查每个@member
是否已在每个函数中正确初始化-这有点恼人.我宁愿写:
Notice that I have to check again and again if each @member
has been properly initialized in each function -- this is mildly irritating. I would much rather write:
module Example
def initialize
@handlers = {}
@unhandled = []
@all_handlers = []
end
# or
@handlers = {}
@unhandled = []
# ...
end
不必反复确保事物已正确初始化.但是,据我所知这是不可能的.除了将initialize_me
方法添加到Example
并从扩展类调用initialize_me
之外,还有什么方法可以解决此问题?我确实看到了此示例,但是我无法用猴子来修补这些内容Class
只是为了做到这一点.
And not have to repeatedly make sure things are initialized correctly. However, from what I can tell this is not possible. Is there any way around this, besides adding a initialize_me
method to Example
and calling initialize_me
from the extended Class? I did see this example, but there's no way I'm monkey-patching things into Class
just to accomplish this.
推荐答案
module Example
def self.included(base)
base.instance_variable_set :@example_ivar, :foo
end
end
编辑:请注意,这是在设置类实例变量.将模块混入类时,无法创建实例上的实例变量,因为尚未创建这些实例.不过,您可以在mixin中创建一个初始化方法,例如:
Edit: Note that this is setting a class instance variable. Instance variables on the instance can't be created when the module is mixed into the class, since those instances haven't been created yet. You can, though, create an initialize method in the mixin, e.g.:
module Example
def self.included(base)
base.class_exec do
def initialize
@example_ivar = :foo
end
end
end
end
在调用包含类的initialize方法(有人吗?)时,可能有一种方法可以做到这一点.没有把握.但这是另一种选择:
There may be a way to do this while calling the including class's initialize method (anybody?). Not sure. But here's an alternative:
class Foo
include Example
def initialize
@foo = :bar
after_initialize
end
end
module Example
def after_initialize
@example_ivar = :foo
end
end
这篇关于在Mixins中初始化实例变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!