开发者

Make dynamic method calls using NoMethodError handler instead of method_missing

开发者 https://www.devze.com 2022-12-18 00:50 出处:网络
I\'m trying to make an API for dynamic reloading processes; right now I\'m at the point where I want to provide in all contexts a method called reload!, however, I\'m implementing this method on an ob

I'm trying to make an API for dynamic reloading processes; right now I'm at the point where I want to provide in all contexts a method called reload!, however, I'm implementing this method on an object that has some state (so it can't be on Kernel).

Suppose we have something like

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

Inside the run_in_worker method there is a code like the following:

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

So I'm doing it this way because I want to make the reload! method available in any nested context开发者_运维技巧, and I don't wanna mess the block I'm receiving with an instance_eval on the worker instance.

So my question is, is there any complications regarding this approach? I don't know if anybody has done this already (haven't read that much code yet), and if it has been done already? Is there a better way to achieve the objective of this code?


Assuming i understand you now, how about this:

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

Using this method every object that invokes the reload! method is modifying the same shared state since my_object is captured by the block passed to define_method


what's wrong with doing this?

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


It sounds like you just want every method to know about an object without the method or the method's owner having been told about it. The way to accomplish this is a global variable. It's not generally considered a good idea (because it leads to concurrency issues, ownership issues, makes unit testing harder, etc.), but if that's what you want, there it is.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号