don*_*ior 2 ruby metaprogramming
我有两个A和B类,它们都有一些选项,通常我会用一个Hash来存储选项,比如@options[:name]='xxxx'; 现在我想用元编程重构它,
class A
set_option :name, "james"
set_option :address, "some street"
def hello
puts @options[:name]
puts @options[:address]
end
end
class B
set_option :age, 18
def greeting
put @options[:age]
end
end
Run Code Online (Sandbox Code Playgroud)
这里我想用来set_option将键和值对设置为一个哈希实例@options,我该怎么办呢?
此外,我想将解决方案包装到一个单独的模块中.
更新:
首先,感谢你所有的答案对我都有价值,让我更清楚,现在我意识到我想要的东西不是那么正确,那么如果我提出这样的问题呢?
option来代替@options?@@options不起作用?我希望不同的类可以有不同的哈希实例.```像这样:
class A
set_option :name, "james"
set_option :provider, 'twitter'
def hello
puts option[:name]
end
end
class B
set_option :name, "not james"
def greeting
put option[:name]
end
end
Run Code Online (Sandbox Code Playgroud)
经过深思熟虑后,我认为我真正想要的是不同类的不同选项哈希实例,而不是类的实例.
这是我想要的,它可以工作.
module HasOptions
def self.included(cls)
cls.class_eval do
def self.set_option(key, value)
options[key] = value
end
def self.options
@options ||= {}
end
def options
self.class.options
end
end
end
end
class Baz
include HasOptions
set_option :name, "bad"
def greeting
puts options[:name]
end
end
class Foo
include HasOptions
set_option :name, "foo"
def greeting
puts options[:name]
end
end
Run Code Online (Sandbox Code Playgroud)
感谢你的帮助.
正如您尝试的那样使用实例变量将无法正常工作.但是,您可以使用以下方法:
module HasOptions
def self.included(cls)
cls.class_eval do
def self.set_option(key, value)
(@@options ||= {})[key] = value
end
end
end
def options
@options ||= @@options.dup
end
end
Run Code Online (Sandbox Code Playgroud)
此实现允许您设置每个实例选项,而不会覆盖所有实例的公共选项.