在Ruby中,函数可以返回多个*值。 Ruby函数是否可以确定其调用代码所期望的返回值的数量?
例如:
a = f() # caller expects one return value
a, b = f() # caller expects two return values
a, b, c = f() # caller expects three return values
如果我们让r
为预期返回值的数量,是否可以编写函数f
以便找到r
?
具体来说,我们如何更改下面rcount
的定义,以便通过以下测试:
a, b = rcount()
puts "#{a},#{b}" # FAIL, DESIRED: "2,1" ACTUAL: "1,"
a, b, c = rcount()
puts "#{a},#{b},#{c}" # FAIL, DESIRED: "3,2,1" ACTUAL: "1,,"
a, b, c, d = rcount()
puts "#{a},#{b},#{c},#{d}" # FAIL, DESIRED: "4,3,2,1" ACTUAL: "1,,,"
rcount
的定义如下:
def rcount()
ret = []
r = nil # <== Q. IS IT POSSIBLE TO GET r PROGRAMMATICALLY?
r ||= 1
last = r - 1
(0..last).each do |i|
ret[i] = r - i
end
ret
end
*实际上多个返回值是语法糖,实际返回值是单个数组。所有Ruby函数都只返回一个值。
答案 0 :(得分:8)
Ruby函数总是只有一个返回值。你使用的是ruby的一个相当漂亮的功能,它允许使用逗号运算符来构造数组。这类似于splat(星号)运算符,可以用作反向运算符。
考虑这个例子
def rcount(number)
# this returns an array containing the 1 till number
(1..number).to_a
end
array = rcount(3)
# array is set to [1, 2, 3]
a, b, c = rcount(3)
# a is set to 1
# b is set to 2
# c is set to 3
x, y = rcount(3)
# x is set to 1
# y is set to 2
# the last value is thrown away
r, t, z = rcount(2)
# r is set to 1
# t is set to 2
# z is set to nil
基本上,没有必要检查返回数组中的数字或元素,至少在语法正确性方面是这样。如果您需要依赖于总是具有完全匹配数量的数组元素的事实,则应该使用测试来检查它。
请记住,你实际上是在这里处理数组。由于数组的解构是在函数返回数组之后完成的,因此无法知道之后对该值做了什么。这完全独立于函数调用。
作为最后的建议,如果你真的需要在一个生产软件中使用这样的东西,你应该认真地重新考虑你的设计,因为这样的东西引入了重要的功能耦合。鸭子打字是一种礼物。慷慨地使用它。
答案 1 :(得分:3)
没有。 Ruby环境不会为您提供该信息。您可以使用异常和ParseTree来查找调用代码的外观,但这样做太过分了:)
答案 2 :(得分:-1)
使用来电者获取文件和行号。 然后,您可以读取代码行以查看函数的调用方式:
def get_line(f,n)
File.open(f,'r') do |fh|
i = 0
fh.each_line do |ln|
i+=1
return ln if i==n
end
end
end
def f()
if caller.first=~/([^:]+):(\d+)/
f,n = $1,$2.to_i
line = get_line(f,n)
case line
when /\w+,\s*\w+\s*=\s*f\(/
return [2, 3]
when /=\s*f\(/
return 1
else
puts 0
end
end
end
f()
a = f()
puts "a = #{a}"
b,c = f()
puts "b,c = #{b},#{c}"
输出结果为:
0
a = 1
b,c = 2,3
但是,是的...... 此上下文不是Ruby语言的一部分: