I am not sure whether this is actually possible, but I wasn't able to find a clear answer anywhere. Also I find it hard to define my question in mere 'search terms'. So I am sorry if this has already been answered somewhere else, I could not find it.
What I would like to know is if it is possible to create a Proc that holds a method that isn't defined in the location where the Proc is being defined. Then I would like to put that instance inside another class that does have the method, and run THAT one with the provided arguments.
Here is a sample of what I want to accomplish, but don't know how.
class MyClassA
# This class does not have the #run method
# but I want Class B to run the #run method that
# I invoke from within the Proc within this initializer
def initialize
Proc.new { run 'something great' }
end
end
class MyClassB
def initialize(my_class_a_object)
my_class_a_object.call
end
# This is the #run method I want to invoke
def run(message)
puts message
end
end
# This is what I execute
my_class_a_object = MyClassA.new
MyClassB.new(my_class_a_object)
The following error is produced
NoMethodError: undefined method for #<MyClassA:0x10017d878>
And I think I understand why, it is because it is trying to invoke the run
method on the MyClassA
instance rather than the one in MyClassB
. However, is there a way I could make the run
command invoke MyClassB
's run
instance method?
There are two problems with your code:
MyClassA.new
does not return the value of initialize
it ALWAYS returns an instance of MyClassA
.
You cannot just call the proc, you have to use the instance_eval
method to run it in the context of MyClassB
Here is your code corrected to work as you want:
class MyClassA
def self.get_proc
Proc.new { run 'something great' }
end
end
class MyClassB
def initialize(my_class_a_object)
instance_eval(&my_class_a_object)
end
# This is the #run method I want to invoke
def run(message)
puts message
end
end
# This is what I execute
my_class_a_object = MyClassA.get_proc
MyClassB.new(my_class_a_object) #=> "something great"