如何在 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确实支持Procs 形式的一等过程,但是,由于它们与任何其他对象一样只是对象,因此您可以传递任意数量的对象:

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 字面量后,Procs 在语法上几乎和块一样轻量,因此不再有太大区别:

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 个块的主要内容,如果未能解决你的问题,请参考以下文章

如何在nodejs中产生按键检测?

如何在SQL中产生交叉式数据表(枢纽分析表)Part 2(PIVOT,UNPIVOT)

如何在Haskell中产生无穷大?

spring中产生bean的几种方式

如何通过输入/答案在 Python 中产生打字效果?

如何在sql中产生随机的十六进制颜色?