在没有参数`& block`的方法中,在参数`& block`和`yield self`的方法中使用`yield self`有什么不同?

时间:2017-04-13 11:32:54

标签: ruby yield

我理解

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

def a()
  yield self
end
如果我假设存在这样的块a {},那么

会导致相同的结果。我的问题是 - 因为我偶然发现了一些类似的代码,它是否有任何区别或是否有任何优势(如果我不使用变量/引用块):

def a(&block)
  yield self
end

这是一个具体案例,我不理解使用&block

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

2 个答案:

答案 0 :(得分:8)

我能想到的唯一优势就是内省:

def foo;       end
def bar(&blk); end

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

IDE和文档生成器可以利用这一点。但是,它不会影响Ruby的参数传递。调用方法时,无论是声明还是调用,都可以传递或省略一个块。

答案 1 :(得分:1)

之间的主要区别
def pass_block
  yield
end
pass_block { 'hi' } #=> 'hi'

def pass_proc(&blk)
  blk.call
end
pass_proc  { 'hi' } #=> 'hi'

blkProc的实例,是一个对象,因此可以传递给其他方法。相比之下,块不是对象,因此无法传递。

def pass_proc(&blk)
  puts "blk.is_a?(Proc)=#{blk.is_a?(Proc)}"
  receive_proc(blk)
end

def receive_proc(proc)
  proc.call
end

pass_proc { 'ho' }
blk.is_a?(Proc)=true
  #=> "ho"