有没有办法知道ruby方法是否被重新定义了?

bksxznpy  于 2022-11-04  发布在  Ruby
关注(0)|答案(2)|浏览(145)

我想知道类上的方法是否被重定义了。
用例:在ruby-clock版本1中,定义一个对象的方法是API的一部分。在版本2中,这样做会破坏行为,应该使用不同的API。
我最后做了什么:https://github.com/jjb/ruby-clock/pull/28/files
最好的情况是我可以使用某种元编程来注意到它发生的时间。:


# this is example code which does not work

class MyClass
  def my_method
    puts "hello"
  end

  # this is not real! it's an example of what i hope is somehow possible
  def self.method_defined(m, *args, &block)
    if :my_method == m
      raise "you should not redefine my_method!"
    end
  end
end

也可以接受的是,如果我可以检查回来后,看看它是否有变化。


# this is example code which does not work

class MyClass
  def my_method
    puts "hello"
  end

  @@my_method_object_id = get_method_object_id(:my_method)
end

# later, when app initialization is done, check if the user redefined the method

# this is not real! it's an example of what i hope is somehow possible

def self.method_defined(m, *args, &block)
  if MyClass.get_method_object_id(:my_method) != MyClass.my_method_object_id
    raise "you should not redefine my_method!"
  end
end

注意MyClass.method(:my_method)在ruby中是真实的的,但它总是产生一个新对象。

34gzjxbg

34gzjxbg1#

这听起来很像XY问题。我不认为你应该走这条路-如果你发现自己在与Ruby对象模型作斗争,你很可能选择了错误的工具。
但是为了完整性的考虑...... Module中有几个回调函数可以帮助实现像这个一样疯狂的想法。特别是,每次定义某个示例方法时都会调用Module#method_added。因此,我们可以像这样做smth.(非常肮脏的例子):

class C
  @foo_counter = 0

  def self.method_added(name) 
    if name == :foo
      @foo_counter += 1
      if @foo_counter > 1
        raise "Don't redefine foo!"
      end
    end  
  end  

  def foo
    "foo"
  end  
end

现在,如果试图打开C并重新定义foo,则会发生以下情况(例如,PRY会话):

pry(main)> class C
pry(main)*   def foo
pry(main)*     "bar"
pry(main)*   end  
pry(main)* end

RuntimeError: Don't redefine foo!

所以你 * 可以 * 做你想做的事(在某种程度上--这是Ruby,所以有什么能阻止你先重新定义这个烦人的钩子呢?:),但是请不要这样做。你只会得到麻烦...

goucqfw6

goucqfw62#

您可以使用回调BasicObject#singleton_method_added。
第一个

相关问题