Reputation: 132247
I want to store several different methods in an array in Ruby. Suppose I want to store the type
method twice:
[type, type]
doesn't store two entries of type
in an array; it executes type
twice, and stores the results in the array. how do I refer explicitly to the method object itself?
(this is just a simplified version of what I really want.)
EDIT: on second thoughts, it bothers me that the solution proposed below avoids the problem by passing the name of the method. how do you pass the method object itself? for example, what if you pass [:type, :type] to a method that has an alternative resolution for type? how can you pass the type method object itself?
Upvotes: 18
Views: 16579
Reputation: 54593
If you're thinking about doing method references in Ruby, you're doing it wrong.
There is a built-in method in Ruby called method
. It will return a proc version of the method. It is not a reference to the original method, though; every call to method
will create a new proc. Changing the method won't affect the proc, for example.
def my_method
puts "foo"
end
copy = method(:my_method)
# Redefining
def my_method
puts "bar"
end
copy.call
# => foo
When you want to store pieces of code, and don't want to use regular methods, use procs.
stack = [proc { do_this }, proc { do_that }]
stack.each {|s| s.call }
Upvotes: 13
Reputation: 237060
If you want to store a method rather than the result of calling a method or just the message you'd send to invoke it, you need to use the method
method on the owning object. So for example
"hello".method(:+)
will return the + method of the object "hello", so that if you call it with the argument " world", you'll get "hello world".
helloplus = "hello".method(:+)
helloplus.call " world" # => "hello world"
Upvotes: 39
Reputation: 13026
[:type, :type].collect { |method_name| self.send(method_name) }
Alternatively, if the method is part of an object:
method = obj.method(:type)
values = [method.call, method.call]
Upvotes: 1