如何在 1 种方法中产生 2 个块
Posted
技术标签:
【中文标题】如何在 1 种方法中产生 2 个块【英文标题】:How to yield 2 blocks in 1 method 【发布时间】:2014-06-05 08:11:59 【问题描述】:如何在同一方法中生成两个不同的块
示例代码:
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)
有什么建议吗?哪里出了问题?谢谢
【问题讨论】:
【参考方案1】:块是一种将单个匿名过程传递给方法的轻量级方式。因此,根据定义,不能有两个块传递给一个方法。这不仅在语义上不可能,甚至在句法上也不可能。
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
s 在语法上几乎和块一样轻量,因此不再有太大区别:
by_two(10, 300, -> x p x * 2 , -> x x + 100 )
# 20
# => 400
【讨论】:
【参考方案2】:你不能在一个方法中产生两个块。
但你可以采取两个触发。
def by_two(n, a, pr1, pr2)
pr1.call(n)
pr2.call(a)
end
by_two(10, 300, proc1, proc2)
【讨论】:
【参考方案3】:您的问题的答案是:如果您坚持阻止,您将无法做到! Ruby 不支持每个方法有多个块。解决此问题的一种方法是将两个 proc 作为变量传递,如下所示:
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)
输出相同。
【讨论】:
以上是关于如何在 1 种方法中产生 2 个块的主要内容,如果未能解决你的问题,请参考以下文章