Search code examples
rubyyield

Is there any difference in using `yield self` in a method with parameter `&block` and `yield self` in a method without a parameter `&block`?


I understand that

def a(&block)
  block.call(self)
end

and

def a()
  yield self
end

lead to the same result, if I assume that there is such a block a {}. My question is - since I stumbled over some code like that, whether it makes any difference or if there is any advantage of having (if I do not use the variable/reference block otherwise):

def a(&block)
  yield self
end

This is a concrete case where i do not understand the use of &block:

def rule(code, name, &block)
  @rules = [] if @rules.nil?
  @rules << Rule.new(code, name)
  yield self
end

Solution

  • The only advantage I can think of is for introspection:

    def foo;       end
    def bar(&blk); end
    
    method(:foo).parameters  #=> []
    method(:bar).parameters  #=> [[:block, :blk]]
    

    IDEs and documentation generators could take advantage of this. However, it does not affect Ruby's argument passing. When calling a method, you can pass or omit a block, regardless of whether it is declared or invoked.