我正在尝试将函数分配给变量,这样做感觉很自然:
def myfunction(num=3)
num
end
varfunc = myfunction
puts varfunc # it outputs 3 here, as expected
这有几个问题。
首先,myfunction 不是函数,而是方法。方法不是 Ruby 中的对象。您只能将对象分配给变量,因此,由于方法不是对象,因此您不能将它们分配给变量。
其次,您没有将方法myfunction 分配给变量varfunc,因为正如我上面解释的那样,您不能这样做。您正在调用方法myfunction 并将其返回值分配给变量varfunc。在 Ruby 中,括号对于方法调用是可选的。
第三,即使 if 这个 did 也能像你期望的那样工作,即 if 方法是对象(它们不是),那么你展示的代码仍然不应该像你看到的那样工作。 如果 varfunc 是 一个函数,那么代码将不是“在这里输出 3,正如预期的那样”,因为你会期望 varfunc成为一个函数,而不是一个整数,它应该输出类似
的东西
#<Function:0xdeadbeef4815162342>
因此,它确实输出 3 的事实是不预期的,事实上清楚地告诉您您的预期是错误的。
您的逻辑不一致:在第 5 行,您假设去掉括号不会调用myfunction,而是引用它,在第 7 行,您假设去掉括号将不会引用varfunc,而是调用它。这没有任何意义。
但这并不容易......
puts varfunc(12)
给我这个控制台错误:
test.rb:8:in `<main>': undefined method `varfunc'
for main:Object (NoMethodError)
那么如何传递参数呢?非常感谢。
varfunc 是一个变量,而不是一个方法。您只能将参数传递给方法,而不能传递给变量。您需要将varfunc 设为一个方法。
有两种方法可以解决这个问题。一种方法是使 myfunction 成为 Proc 对象,这是 Ruby 最接近“函数”的等效对象:
myfunction = -> (num=3) { num }
varfunc = myfunction
puts varfunc
# #<Proc:0x007f909285f640@(irb):1 (lambda)>
# *This* is the output you would expect from `puts`ing a "function"
puts varfunc.()
# 3
puts varfunc.(12)
# 12
另一种可能性是使用反射来获取myfunction 方法的Method 包装器对象,使用Object#method 方法:
def myfunction(num=3) num end
varfunc = method(:myfunction)
puts varfunc
# #<Method: Object#myfunction>
puts varfunc.()
# 3
puts varfunc.(12)
# 12