如何传递函数而不是块

时间:2012-12-19 04:28:20

标签: ruby functional-programming

  

可能重复:
  Shorter way to pass every element of an array to a function

我知道这会奏效:

def inc(a)
  a+1
end
[1,2,3].map{|a| inc a}

但在Python中,我只需要写:

map(inc, [1,2,3])

[inc(x) for x in [1,2,3])

我想知道我是否可以跳过在Ruby中制作块的步骤,并且这样做了:

[1,2,3].map inc
# => ArgumentError: wrong number of arguments (0 for 1)
# from (irb):19:in `inc'

有没有人有关于如何做到这一点的想法?

3 个答案:

答案 0 :(得分:71)

根据“Passing Methods like Blocks in Ruby”,您可以将方法作为块传递:

p [1,2,3].map(&method(:inc))

老实说,不知道这是否比滚动你自己的街区要好得多。

如果您的方法是在您正在使用的对象的类上定义的,则可以这样做:

# Adding inc to the Integer class in order to relate to the original post.
class Integer
  def inc
    self + 1
  end
end

p [1,2,3].map(&:inc)

在这种情况下,Ruby会将符号解释为实例方法名称,并尝试在该对象上调用该方法。


你可以在Python中将函数名称作为第一类对象传递但不在Ruby中传递的原因是因为Ruby允许你调用一个没有括号的零参数的方法。 Python的语法,因为它需要括号,防止传递函数名和调用没有参数的函数之间的任何可能的歧义。

答案 1 :(得分:9)

不回答您的问题,但如果您真的只想增加所有变量,那么Integer#next

4.next
#=> 5

[1,2,3].map(&:next)
#=> [2, 3, 4]

答案 2 :(得分:-10)

def inc(a)
  a + 1 
end

p [1,2,3].map{|a| inc a}