如何修改传递给块的范围?

时间:2011-03-07 17:41:05

标签: ruby

我已经和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是多么容易。 :)

1 个答案:

答案 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

在你班上。