【问题标题】:How can i treat functions like objects in ruby?我如何处理像 ruby​​ 中的对象这样的函数?
【发布时间】:2016-10-22 14:35:07
【问题描述】:

在我的 ruby​​ 项目中,我想创建一个任务管理器类,它会定期迭代一组已注册的函数。我需要将函数作为参数传递给寄存器函数,创建一个线程,当线程计时器触发时,它需要调用数组中的每个函数。

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

基本上,这就是我想做的,但我不确定如何使用to_proccall 来推入函数并调用它们。

其他解决方案也值得赞赏,但我不想避免学习将函数作为参数传递,将它们放入数组并调用它们。

谢谢。

【问题讨论】:

  • Ruby 没有函数。您的问题不清楚。

标签: ruby


【解决方案1】:

使用method method 将类方法获取为可调用对象(在本例中为Method 实例),然后将& 应用于这些对象:

TaskMan.register_func &Callee.method(:func_0)
TaskMan.register_func &Callee.method(:func_1)

现在你可以把各种东西扔到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.

【讨论】:

    【解决方案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_0func_1。要使用数组迭代调用它们,您可以这样做

      methods = [:func_0, :func_1]
      methods.each do |m|
        send(m)
      end
      

      【讨论】:

      • 在 OP 的示例中,您不能只调用 send(m),在他的情况下,函数的接收者不是 self
      猜你喜欢
      • 2015-06-18
      • 1970-01-01
      • 1970-01-01
      • 2016-04-09
      • 2016-05-11
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多