Ruby块和收益率

时间:2011-01-04 04:25:59

标签: ruby

什么是

yield self if block

它只是意味着如果在启动方法上附加了一个块,它会在最后被调用吗?

def initialize options = {}, &block

  @type = self.class.to_s.split('::').last.downcase.to_sym
  @version = options.delete(:version) || 1.0
  @language = options.delete(:language) || :en
  @query = options.delete(:query)
  @api_key = options.delete(:key) || :notsupplied
  @options = options
  raise Error, 'Do not initialize Google::Search; Use a subclass such as  Google::Search::Web' if @type == :search
  yield self if block

2 个答案:

答案 0 :(得分:2)

是的,差不多。所以你可以这样做:

Google::Search::Web.new do |search|
  # ...
end

(尽管从软件设计的角度来看,在构造函数中运行用户指定的代码对我来说似乎总是很奇怪。更好的方法是FileIO做什么,其中{{1与open几乎完全相同,只是new运行传入的块,而open则没有。)

答案 1 :(得分:2)

当你写这样的方法时:

def foo( a, b, &c )
  ...
end

如果将块传递给方法,则将变量c设置为Proc实例,如果未传递块,则将变量nil设置为nil。因为yield if block_given?是非真值,所以您引用的方法是测试是否传递了一个块来决定是否屈服。

正如@MarcAndréLafortune所说,更好的代码是:@foo = c。你想要捕获一个块(我能想到的)的唯一时间是:

  1. 为了将其保存到实例变量中以供日后使用:
    • e.g。 @foo[ 42 ]然后稍后调用它并传入值(my_array.select(&@foo)),或将其作为块传递给另一个方法@my_array = initial_values.select(&c)
  2. 或者,将其作为块直接传递给您的方法调用的其他方法:
    • e.g。 {{1}}