How to pass a function instead of a block
RubyFunctional ProgrammingRuby Problem Overview
> Possible Duplicate:
> Shorter way to pass every element of an array to a function
I know this will work:
def inc(a)
a+1
end
[1,2,3].map{|a| inc a}
but in Python, I just need to write:
map(inc, [1,2,3])
or
[inc(x) for x in [1,2,3])
I was wondering whether I can skip the steps of making a block in Ruby, and did this:
[1,2,3].map inc
# => ArgumentError: wrong number of arguments (0 for 1)
# from (irb):19:in `inc'
Does anyone have ideas about how to do this?
Ruby Solutions
Solution 1 - Ruby
According to "Passing Methods like Blocks in Ruby", you can pass a method as a block like so:
p [1,2,3].map(&method(:inc))
Don't know if that's much better than rolling your own block, honestly.
If your method is defined on the class of the objects you're using, you could do this:
# 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)
In that case, Ruby will interpret the symbol as an instance method name and attempt to call the method on that object.
The reason you can pass a function name as a first-class object in Python, but not in Ruby, is because Ruby allows you to call a method with zero arguments without parentheses. Python's grammar, since it requires the parentheses, prevents any possible ambiguity between passing in a function name and calling a function with no arguments.
Solution 2 - Ruby
Does not answer your question but if you really just want to increment all your variables, you have Integer#next
4.next
#=> 5
[1,2,3].map(&:next)
#=> [2, 3, 4]