在Ruby中评估方法参数的顺序是什么?

时间:2016-03-24 17:58:57

标签: ruby

直到my attempt回答this question我一直认为参数是按照我们输入的方式从左到右进行评估的。例如,我们有一些方法:

def foo(a,b,c)

有没有办法随着时间的推移监视Ruby程序中的变量定义和值?如果您致电foo 0,1,2,您如何证明按以下顺序分配的变量?

时间0:a = 0

时间1:b = 1

时间2:c = 2

我意识到我的例子很简单,因为我对a, b, c有相同类型的参数,但是当你引入默认参数,关键字参数和数组参数时,它可能会变得混乱。如果没有人知道答案我会很感激如何确定答案的建议。

基本上相当于this的Ruby。

4 个答案:

答案 0 :(得分:2)

def arg_test(a=Time.now, b=Time.now)
  puts "left to right" if a < b
end

arg_test #=> left to right

答案 1 :(得分:2)

ISO Ruby语言规范说,参数按照它们在程序文本中出现的顺序绑定到参数。但是,该规范含糊不清,这是否意味着它们是按照该顺序进行评估

RubySpec,AFAICS对方法论据的评估顺序一无所知。

所以,答案似乎是:方法参数没有保证的评估顺序。它可以在不同的实现之间不同,它可以在相同实现的不同版本之间不同,它可以在相同实现的相同版本的两次运行之间不同,甚至可以在对同一方法的两次调用之间不同。它们可以并行评估。

你只是不知道。

答案 2 :(得分:1)

也许您可以记录对象的初始化,稍后在堆栈中查看它们。

module Record
  @@stack = []
  def initialize *; super; @@stack.push(self) end
  def self.stack; @@stack end
end

class String
  prepend Record
end

def foo a, b, c; end

foo(String.new("x"), String.new("y"), String.new("z"))
Record.stack # => ["x", "y", "z"]

在这种情况下,abc按此顺序进行评估。

使用默认值,您可以看到:

def foo a, b, c = String.new("c"); end

foo(String.new("x"), String.new("y"))
Record.stack # => ["x", "y", "c"]

答案 3 :(得分:0)

对于任何来这里查找参数分配顺序(问题在我发帖时要问)而不是参数分配顺序的人。我一直以为它们是按编写顺序进行评估的,直到我尝试编写一些奇怪的代码并得到一个奇怪的结果。 steenslag给了我一个如何测试的想法:

def arg_test(a, b)
  puts([a, b].inspect '- out of order!') if a > b
end

1000000.times {
  arg_test(Time.now, Time.now)
}

这将导致没有输出。因此,似乎它们是按顺序分配的,而我的其他代码可能只是一个错误。