首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby函数有可能检测请求的返回值的数量吗?

问Ruby函数有可能检测请求的返回值的数量吗?
EN

Stack Overflow用户
提问于 2011-11-20 11:04:01
回答 3查看 559关注 0票数 3

在Ruby中,一个函数可以返回多个*值。Ruby函数可以确定它的调用代码期望多少个返回值吗?

例如:

代码语言:javascript
复制
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的定义,如下所示,即通过以下测试:

代码语言:javascript
复制
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的定义如下:

代码语言:javascript
复制
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函数都只返回一个值。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-11-20 11:08:44

不是的。Ruby环境不会提供这些信息。您可以使用exception和ParseTree来找出调用代码的样子,但这有点过头了:)

票数 3
EN

Stack Overflow用户

发布于 2011-11-21 02:09:58

Ruby函数总是只有一个返回值。您使用的是ruby的一个相当好的特性,它允许使用逗号运算符来解构数组。这与可以用作反转运算符的拆分(星号)运算符类似。

考虑这个例子

代码语言:javascript
复制
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

因此,基本上不需要检查返回数组中的数量或元素,至少不需要检查语法的正确性。如果您需要依赖于始终具有精确匹配数量的数组元素这一事实,则应该使用测试来检查这一点。

只需记住,您在这里实际上是在处理数组。而且,由于数组的解构是在函数返回数组之后完成的,因此它无法知道之后如何处理该值。这完全独立于函数调用。

作为最后的建议,如果你真的需要在一个生产软件中使用这样的东西,你应该认真地重新考虑你的设计,因为这样的东西会引入大量的功能耦合。鸭子打字是一种天赋。大方地使用它。

票数 8
EN

Stack Overflow用户

发布于 2013-06-04 10:19:23

使用caller获取文件和行号。然后,您可以阅读这行代码来查看函数是如何调用的:

代码语言:javascript
复制
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}"

输出为:

代码语言:javascript
复制
0
a = 1
b,c = 2,3

但是,是的。此上下文不是Ruby语言的一部分:

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8199154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档