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:
- In order to save it into an instance variable for use later:
- e.g.
@foo = cand then later either invoke it and pass in values (@foo[ 42 ]), or pass it as a block to another methodmy_array.select(&@foo).
- e.g.
- Or, pass it along directly as a block to other methods called by your method:
- e.g.
@my_array = initial_values.select(&c)
- e.g.
加载中,请稍侯......
精彩评论