我正在扩展一个类来接受DSL。实例应始终使用默认值进行响应,但代码可能会更改。当我调用设置who_am_i
方法的i_am
时,下面的代码工作正常,但我无法弄清楚如何设置默认方法。
module Helper
def i_am
"Default code"
end
def who_am_i
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
def i_am
"This was executed in class: \#{self.class.to_s}"
end
EOS
end
end
class Test
extend Helper
end
t = Test.new
t.i_am
我可以通过这样做来完成这项工作:
class Test2
extend Helper
include Helper
end
t2 = Test2.new
t2.i_am
但这看起来很怪异。想法?
答案 0 :(得分:3)
您需要使用包含的方法/钩子。每当给定模块包含在其他类或模块中时,它就会被运行,这个类或模块用于参数。在你的情况下你想要:
module Helper
def i_am
"Default code"
end
def self.included mod
mod.extend ClassMethods
end
module ClassMethods
def who_am_i
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
def i_am
"This was executed in class: \#{self.class.to_s}"
end
EOS
end
end
end
class Tester
include Helper
end
答案 1 :(得分:1)
啊哈!
答案是使用module.included()使其扩展类。这样你就可以使用“include Helper”了 “include”部分将调用“Helper.included”并传递给调用者,并使用它来扩展它!
参考:http://www.railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/
module Helper
def i_am
"Default code"
end
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def who_am_i
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
def i_am
"This was executed in class: \#{self.class.to_s}"
end
EOS
end
end
end
class Test
include Helper
end