Reputation: 325
In my ruby project, i want to create a task manager class which will periodically iterate through an array of registered functions. I need to pass functions as argument to the register function, create a thread and when the thread timer fires, it needs to call each function in array.
class TaskMan
@@func_array = Array.new
def self.register_func &arg_func
@@func_array.push arg_func
end
def self.run_server
loop do
@@func_array.each do |func|
func.call
end
sleep 60
end
end
end
class Callee
def self.func_0
puts "func_0 called."
end
def self.func_1
puts "func_1 called."
end
end
TaskMan.register_func Callee.func_0
TaskMan.register_func Callee.func_1
taskman_thread = Thread.new do
TaskMan.run_server
end
taskman_thread.join
Basically, this is what i want to do, but i'm not sure how to use to_proc
and call
, to push in the functions and call them.
Other solutions are also appreciated, but i don't want to avoid learning passing functions as arguments, putting them in array and calling them.
Thanks.
Upvotes: 0
Views: 76
Reputation: 434755
Use the method
method to get the class methods as callable objects (Method
instances in this case) and then apply &
to those objects:
TaskMan.register_func &Callee.method(:func_0)
TaskMan.register_func &Callee.method(:func_1)
Now you can throw all sorts of things into the func_array
:
TaskMan.register_func &SomeClass.method(:m) # class method
TaskMan.register_func &some_object.method(:m) # an instance method
TaskMan.register_func &some_lambda # a lambda function
TaskMan.register_func { puts "pancakes" } # a block
# etc.
Upvotes: 2
Reputation: 9762
You can instead pass the receiver and the function you intend calling as below:
class TaskMan
@@func_array = Array.new
def self.register_func(receiver, func)
@@func_array.push([receiver, func])
end
def self.run_server
loop do
@@func_array.each do |(receiver, func)|
receiver.method(func).call
end
sleep 60
end
end
end
class Callee
def self.func_0
puts "func_0 called."
end
def self.func_1
puts "func_1 called."
end
end
TaskMan.register_func Callee, :func_0
TaskMan.register_func Callee, :func_1
taskman_thread = Thread.new do
TaskMan.run_server
end
taskman_thread.join
Upvotes: 1
Reputation: 7308
Let's say you have methods func_0
and func_1
. To call them using array iteration you can do this
methods = [:func_0, :func_1]
methods.each do |m|
send(m)
end
Upvotes: 0