如何在1种方法中产生2个块

时间:2014-04-21 09:23:33

标签: ruby methods yield proc

如何在同一方法中使用两个不同的块

示例代码:

def by_two(n,a)
    yield n
    yield a
end

proc1 = proc {|x| p x * 2}
proc2 = proc {|x| x + 100}

by_two(10, 300, &proc1, &proc2)

错误就是这样 -

main.rb:7: syntax error, unexpected ',', expecting ')'
by_two(10, 300, &proc1, &proc2)

有什么建议在哪里,哪些是错的?感谢

3 个答案:

答案 0 :(得分:9)

您不能在方法中产生两个块。

但是你可以进行两次触发。

def by_two(n, a, pr1, pr2)
  pr1.call(n)
  pr2.call(a)
end
by_two(10, 300, proc1, proc2)

答案 1 :(得分:9)

块是将单个匿名过程传递给方法的轻量级方法。因此,按照定义,不能将两个块传递给方法。它不仅在语义上不可能,甚至不可能语法

Ruby 支持Proc s形式的一流程序,但由于它们只是像任何其他对象一样的对象,你可以传递尽可能多的对象想:

def by_two(n, a, proc1, proc2)
  proc1.(n)
  proc2.(a)
end

proc1 = proc {|x| p x * 2}
proc2 = proc {|x| x + 100}

by_two(10, 300, proc1, proc2)
# 20
# => 400

自从在Ruby 1.9中引入lambda文字以来,Proc几乎与块一样轻量级,因此不再有太大的区别:

by_two(10, 300, -> x { p x * 2 }, -> x { x + 100 })
# 20
# => 400

答案 2 :(得分:4)

你的问题的答案是:如果你坚持要阻止你就不能这样做! Ruby不支持每个方法多个块。解决这个问题的方法是将两个过程作为变量传递:

def by_two(n,a, proc1=nil, proc2=nil)
  if proc1 || proc2
    proc1.yield n if proc1
    puts proc2.yield a if proc2
  else
    puts "no procs"
  end
end

proc1 = proc {|x| p x * 2}
proc2 = proc {|x| x + 100}
by_two(10, 300, proc1, proc2)

by_two(10, 300, proc1)

by_two(10, 300)

输出:

20
400
20
no procs

另一种可能性是:

NO_OP = proc {}

def by_two(n,a, proc1=NO_OP, proc2=NO_OP)
  if proc1 == NO_OP && proc2 == NO_OP
    puts "no procs"
  else
    proc1.yield n
    proc2.yield a
  end
end

proc1 = proc {|x| p x * 2}
proc2 = proc {|x| p x + 100}
by_two(10, 300, proc1, proc2)

by_two(10, 300, proc1)

by_two(10, 300)

它具有相同的输出。