开发者

Ruby Blocks and Yield

What is the

yield self if block

does it only mean if there was a block attached to the initiation method it would be called at the end?

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,开发者_如何学Python 'Do not initialize Google::Search; Use a subclass such as  Google::Search::Web' if @type == :search
  yield self if block


Yep, pretty much. So you can do something like:

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

(Though, from a software design point of view, running user-specified code in a constructor always seemed strange to me. A better approach is what File and IO do, where open does pretty much the same thing as new, except that open runs the passed-in block, whereas new does not.)


When you write a method like this:

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

Then the variable c is set to a Proc instance if you pass a block to the method, or set to nil if you don't pass a block. Because nil is a non-truth value, the method you cite is testing to see if a block was passed to decide whether to yield or not.

As @MarcAndréLafortune says, the better code is: yield if block_given?. The only times you want to capture a block (that I can think of) are:

  1. In order to save it into an instance variable for use later:
    • e.g. @foo = c and then later either invoke it and pass in values (@foo[ 42 ]), or pass it as a block to another method my_array.select(&@foo).
  2. Or, pass it along directly as a block to other methods called by your method:
    • e.g. @my_array = initial_values.select(&c)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜