#ruby
#ruby
Вопрос:
В моем проекте ruby я хочу создать класс диспетчера задач, который будет периодически выполнять итерации по массиву зарегистрированных функций. Мне нужно передать функции в качестве аргумента функции register, создать поток, и когда сработает таймер потока, ему нужно вызвать каждую функцию в массиве.
class TaskMan
@@func_array = Array.new
def self.register_func amp;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
В принципе, это то, что я хочу сделать, но я не уверен, как использовать to_proc
и call
, чтобы вводить функции и вызывать их.
Другие решения также приветствуются, но я не хочу избегать обучения передаче функций в качестве аргументов, помещая их в массив и вызывая их.
Спасибо.
Комментарии:
1. В Ruby нет функций. Ваш вопрос неясен.
Ответ №1:
Используйте method
метод, чтобы получить методы класса как вызываемые объекты (в данном случае Method
экземпляры), а затем применить amp;
к этим объектам:
TaskMan.register_func amp;Callee.method(:func_0)
TaskMan.register_func amp;Callee.method(:func_1)
Теперь вы можете добавлять всевозможные вещи в func_array
:
TaskMan.register_func amp;SomeClass.method(:m) # class method
TaskMan.register_func amp;some_object.method(:m) # an instance method
TaskMan.register_func amp;some_lambda # a lambda function
TaskMan.register_func { puts "pancakes" } # a block
# etc.
Ответ №2:
Вместо этого вы можете передать приемник и функцию, которую вы собираетесь вызвать, как показано ниже:
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
Ответ №3:
Допустим, у вас есть методы func_0
и func_1
. Чтобы вызвать их с помощью итерации массива, вы можете сделать это
methods = [:func_0, :func_1]
methods.each do |m|
send(m)
end
Комментарии:
1. вы не можете просто вызвать
send(m)
в примере OP, получатель функции не являетсяself
в его случае