代码之家  ›  专栏  ›  技术社区  ›  Roman Gonzalez

使用NoMethodError处理程序进行动态方法调用,而不是缺少方法

  •  1
  • Roman Gonzalez  · 技术社区  · 16 年前

    我正在尝试为动态重新加载过程创建一个API;现在我要在所有上下文中提供一个名为 reload! 但是,我正在一个具有某种状态的对象上实现这个方法(因此它不能在内核上)。

    假设我们有

    WorkerForker.run_in_worker do
      # some code over here...
      reload! if some_condition
    end
    

    里面 run_in_worker 方法有如下代码:

    begin
      worker = Worker.new(pid, stream)
      block.call
    rescue NoMethodError => e
      if (e.message =~ /reload!/) 
        puts "reload! was called"
        worker.reload! 
      else
        raise e
      end
    end
    

    所以我这么做是因为我想 重新加载! 方法在任何嵌套上下文中都可用,并且我不想用 instance_eval 上 worker 实例。

    所以我的问题是,这种方法有什么并发症吗?我不知道是否有人已经这样做了(还没有读那么多代码),以及是否已经这样做了?有没有更好的方法来实现这一准则的目标?

    3 回复  |  直到 16 年前
        1
  •  1
  •   horseyguy    16 年前

    假设我现在理解你的话,这个怎么样:

    my_object = Blah.new
    Object.send(:define_method, :reload!) { 
        my_object.reload!
        ...
    }
    

    使用此方法,调用 reload! 方法正在修改相同的共享状态,因为 my_object 被传递给的块捕获 define_method

        2
  •  0
  •   horseyguy    16 年前

    这样做有什么问题?

    def run_in_worker(&block)
        ...
        worker = Worker.new(pid, stream)
        block.call(worker)
    end
    
    WorkerForker.run_in_worker do |worker|
        worker.reload! if some_condition
    end
    
        3
  •  0
  •   Chuck    16 年前

    听起来你只是想让每个方法都知道一个对象,而没有告诉方法或方法的所有者。实现这一点的方法是一个全局变量。这通常被认为不是一个好主意(因为它会导致并发性问题、所有权问题、使单元测试更加困难等),但是如果这是您想要的,那么它就是。