【问题标题】:Order of execution for multiple procs in RubyRuby 中多个 proc 的执行顺序
【发布时间】:2016-03-15 01:24:05
【问题描述】:

我正在尝试一个愚蠢的示例来了解发送到一个方法的多个 proc。然而,令我惊讶的一件事是执行顺序。我查看了 Proc 文档,但并没有真正找到解释(可能是我看的不够仔细)。

这是一个例子:

def my_block(a, b)
    a.call b.call
end

a = Proc.new { puts "hello" }
b = Proc.new { puts " world" }

my_block a, b

输出:

 world
hello

当在一行中给出多个时,proc 执行似乎是从左到右执行的。有人可以详细解释这种行为吗?

【问题讨论】:

  • 这其实很有趣。现在我正试图研究为什么会发生这种情况!
  • 谢谢@dane。感谢任何帮助或投入。 :)
  • 我可能在想编译器正在将“

标签: ruby proc


【解决方案1】:

这是因为:

a.call b.call

真的是:

a.call(b.call())

所以b.call() 首先像在任何其他编程语言中一样被扩展(并运行),其结果作为参数传递给a

你会希望这会产生错误,但在 Ruby 中,块的额外参数不会导致错误(虽然它是方法的错误)...

您可以使用分号明确告诉 ruby​​ 开始一个新表达式:

a.call; b.call

...但我会说这是非常单调且“非 Ruby”...

【讨论】:

  • 感谢您的解释!当您来自 java 时,很难掌握可选的括号! :)
  • @jaypalsingh 如果您想知道为什么没有看到错误,那是因为call 接收到可变参数或任意数量的参数。在这种情况下,它对它们没有任何作用。
  • 感谢您的编辑。 but in Ruby extra parameter to a block don't result in errors 是一个重要的注意事项,请牢记。
  • @jaypalsingh 如果您使用 lambda 而不是 Proc.new,您会看到错误:wrong number of arguments.
  • @jaypalsingh 我有一个“嗯?”关于这一点的几秒钟;-) 恕我直言,当你没有传递任何参数时离开括号是一个设计错误,可能导致各种边缘条件出错......顺便说一句,CoffeeScript 已修复这是通过允许a.call 'param' 但在不使用参数时需要参数,所以你需要a.call(),它提供了两全其美的效果......嗯嗯......
【解决方案2】:

这仅仅是因为您将它们都放在同一行上,所以 b.call 被称为 a.call 的参数。让它按您期望的那样工作;

def my_block(a, b)
  a.call
  b.call
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多