我应该在def中指定& block参数吗?

时间:2014-04-14 15:47:51

标签: ruby coding-style arguments block function

在Ruby中,指定您的方法是否需要&block更好(样式?)?

只要方法体包含yield,选择似乎只是风格问题。

例如,给定:

def abc1(a, c)
  puts a
  yield
  puts c
end

def abc2(a, c, &block)
  puts a
  yield
  puts c
end

以下两个电话:

abc1('a', 'c') { puts 'b' }
abc2('a', 'c') { puts 'b' }

每次打印并返回相同的内容:

a
b
c
=> nil

所以,如果真的只是风格问题,那么会议(或更好的风格)是什么?

3 个答案:

答案 0 :(得分:5)

使用您当前的代码,第一个更好。当您使用yield时,无需使用&block,因为它是隐式。但是,有一点要提醒,你必须在使用yield时传递一个块,否则会出现错误。虽然可以使用block_given?处理该错误。

Ruby的yield语句从方法体中控制用户指定的块。因此,如果您再次使用&block,则它是多余的,因此不需要使用它。

答案 1 :(得分:3)

重要的是要记住,将块作为参数传递的主要原因是它被转换为对象(类Proc的实例),因此可以传递:

def ab(&block)
  yield "ab"
  cd(&block)
end

def cd(&block)
  yield "cd"
  block.call("cd")
end

ab { |str| puts "In #{str}. Please pass the salt, the pepper and the proc." }
In ab. Please pass the salt, the pepper and the proc.
In cd. Please pass the salt, the pepper and the proc.
In cd. Please pass the salt, the pepper and the proc.

答案 2 :(得分:2)

这是个人品味的问题。两种常见情况如下:

def abc1(a, c)
  puts a
  yield
  puts c
end

当隐式传递块时,通常使用yield,如本例所示。你经常看到的另一个是

def abc2(a, c, &block)
  puts a
  block.call(args)
  puts c
end

这样做的好处是,阅读代码的人可以很容易地看到需要传递一个块。