今天闲来写了个高阶函数
def twice(fn, v) fn(fn(v)) # 调用时说没有定义fn 函数 send fn , (send fn, v) # 这样OK end def appendX(str) str << 'X' end twice(:appendX, 'ooo') #1.为何只能使用send, 而直接调用会报错,也就是说 fn = appendX fn('oo') 这样不行, 感觉不允许这样很不自然啊, 求大神解释原
fn = appendX() fn('oo')
这代码怎么看怎么不对啊?
写错了,fn = method(:appendX)
谢谢,但试了一下还是不对
def app(str) str << '!' end fn = method(:app) fn('ooo') # error 这样还是不行为什么呀 fn.call('ooo') #ok
看来 ruby 的函数名并不是一个普通的符号或者变量名。这点和很多语言的不一样。
为什么有这样的结论?函数名就是变量啊
能举例子吗 如果是个变量那你能把他付给另一个变量吗?你能得到该变量的 class 吗
建议楼主花几分钟看一下基本的语法。这些地方和 Python 不一样的。
Ruby 调用方法可以省略括号,这就意味着:
foo.bar
foo.bar()
foo
foo()
-> x { x << 'str' }
method(:foo)
obj.method(:foo)
call
[]
.()
foo.call 1, 2
Ruby 对象不能直接接括号,能接括号都是方法调用。
回到你开始的代码,可以这么写 (用 Lambda 或者 Method):
def twice fn, v fn.(fn.(v)) end append_x = -> str { str << 'X' } twice append_x, 'ooo' def append_x2 str str << 'X' end twice method(:append_x2), 'ooo'
也可以这么写 (用 symbol 或者字符串):
def twice fn, v send fn, (send fn, v) # 这时 fn 是 Symbol 或者字符串, 不是 Lambda 或者 Method 对象 end def append_x str str << 'X' end twice :append_x, 'ooo'
下面的 Y combinator,留给楼主回去思考:
def Y &f g = -> h, x, *xs { f[h[h], x, *xs] }.curry g[g] end factorial = Y {|f, n| n == 0 ? 1 : n * f[n - 1] } factorial[8]
谢谢