我已经和Ruby一起工作了不到一年的时间,而且我还是不完全理解“是什么让blot成为现实”。特别是我很好奇一个人对一个街区范围的控制程度。例如,假设我有这段代码:
class Blob
attr_accessor :viscosity
def configure(&:block)
block.call self
end
end
blob = Blob.new
blob.configure do |b|
b.viscosity 0.5
end
显然,那里有一个人为的例子。
现在,我从Rails 2迁移到Rails 3时注意到的一件事是,许多采用块的配置方法不再采用非块参数。
例如,在routes.rb中,它曾经是ActionController::Routing::Routes.draw do |map| ... end
,现在它只是ActionController::Routing::Routes.draw do ... end
。但是在块内调用的方法仍然具有适当的上下文,而不需要一遍又一遍地重复块的参数名称。
在我上面的例子中,我希望能够做到:
blob.configure do
viscosity 0.5
end
这样我就可以告诉人们在Ruby中编写DSL是多么容易。 :)
答案 0 :(得分:4)
这使用instance_eval
来实现魔力。有关一些文档,请参阅http://apidock.com/ruby/Object/instance_eval/。 instance_eval
在接收者的上下文中评估一个块(或一个字符串)。
def configure(&block)
self.instance_eval &block
end
您仍然必须在示例块中使用访问器方法viscosity=
,否则您必须定义
def viscosity(value)
@viscosity = value
end
在你班上。