gpt4 book ai didi

ruby-on-rails - Ruby method_added 回调不触发包括模块

转载 作者:数据小太阳 更新时间:2023-10-29 07:11:16 32 4
gpt4 key购买 nike

我想写一点“Deprecate-It”库并经常使用“method_added”回调。但是现在我注意到在包含模块时不会触发此回调。

是否有任何回调或变通方法,以便在某些内容包含到自身时通知类“Foobar”?

用于演示的小 Demo:

# Including Moduls won't trigger method_added callback

module InvisibleMethod
def invisible
"You won't get a callback from me"
end
end

class Foobar
def self.method_added(m)
puts "InstanceMethod: '#{m}' added to '#{self}'"
end

def visible
"You will get a callback from me"
end

include InvisibleMethod
end

[:invisible, :visible, :wont_exist].each do |meth|
puts "#{meth}: #{Foobar.public_method_defined? meth}"
end

结果是:

InstanceMethod: 'visible' added to 'Foobar'
invisible: true
visible: true
wont_exist: false

附加信息:

我真的需要使用像 method_added 这样的钩子(Hook)。

ActiveModel 在运行时通过匿名模块向类添加 public_instance_methods。

最佳答案

问题是包含模块并没有给类添加方法——它只是改变了方法调用链。该链定义了将在哪些类/模块中搜索未为相关类定义的方法。当你包含一个模块时会发生什么是在该链中添加一个条目。

这与在父类(super class)中添加方法完全相同 - 这不会调用 method_added,因为它未在父类(super class)中定义。如果一个子类可以改变父类(super class)的行为,那将是非常奇怪的。

您可以通过为您的类重新定义 include 手动调用为包含的模块添加的方法来解决此问题:

class Foobar
def self.include(included_module)
included_module.instance_methods.each{|m| self.method_added(m)}
super
end
end

而且它比在 Module 中重新定义 included 方法要安全得多 - 更改范围仅限于您自己定义的类。

关于ruby-on-rails - Ruby method_added 回调不触发包括模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9386179/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com