我想为DSL提供一些改进。我能够使用这个例子进行改进:
module ArrayExtras
refine Array do
def speak
puts 'array!'
end
end
end
module MyUniverse
using ArrayExtras
class Thing
def initialize
[1].speak
end
end
end
MyUniverse::Thing.new
打印出“数组!”正好。但是,一旦我引入instance_eval
,就无法找到该方法:
module MyUniverse
using ArrayExtras
class DSL
def initialize(&block)
instance_eval(&block)
end
end
end
MyUniverse::DSL.new do
[1].speak
end
我为[1]得到undefined method
说话:数组(NoMethodError)`
有没有办法让实现在instance_eval中进行优化?
答案 0 :(得分:2)
优化是词法范围的。您正在错误的词汇上下文中激活细化。您需要在调用精炼方法的地方激活它:
module ArrayExtras
refine Array do
def speak
puts 'array!'
end
end
end
module MyUniverse
class DSL
def initialize(&block)
instance_eval(&block)
end
end
end
using ArrayExtras
MyUniverse::DSL.new do
[1].speak
end
# array!
答案 1 :(得分:1)
在某些情况下,您可以通过绑定上的using ArrayExtras
来实现。
module MyUniverse
using ArrayExtras
class DSL
def initialize(&block)
block.binding.eval("using ArrayExtras")
instance_eval(&block)
end
end
end
MyUniverse::DSL.new do
[1].speak
end
这仅在您未在实例中使用类的情况下才有效,仅在binding
是模块或类上下文的情况下才有效,否则eval
将失败,因为{{1} }。
答案 2 :(得分:-1)
如果要优化ruby核心BaseObject
,则需要按以下方式对其进行修改。
module ArrayExtras
refine ::Array do
def speak
puts 'array!'
end
end
end
它将在顶级课程中找到。