为何表达式`Object.singleton_class.instance_method(:refine)`会抛出NameError?
为什么
Object.singleton_class.instance_method(:refine)会抛出NameError? 让我们一步步拆解这个问题:
1. 先搞清楚refine方法的归属
你已经提到Module#refine是Module类的私有实例方法,这意味着:
- 所有Module的实例(包括所有类,因为
Class是Module的子类)都继承了这个方法; - 作为类的
Object(毕竟Object.class == Class),确实可以通过send(:refine)或__send__(:refine)调用它——因为方法查找链会沿着Object → Class → Module找到refine的定义。
2. 理解Object.singleton_class的作用
Object.singleton_class是Ruby为Object这个单独对象创建的专属类,它里面只包含Object独有的方法(比如你用def Object.my_custom_method定义的方法)。而refine并不是Object的专属方法,它是所有类都能继承的通用方法,属于Module/Class的实例方法体系,和Object的单例类没有直接关系。
3. instance_method的查找规则
Module#instance_method这个方法的核心是:查找当前类(或其超类)中定义的公共/受保护实例方法。对于继承来的私有方法,它不会主动去检索——这就是问题的关键!
refine是Module定义的私有实例方法,虽然Object.singleton_class的超类是Class(而Class继承了Module的refine),但instance_method不会去查找继承链中的私有方法,所以会抛出NameError。
那如何正确获取refine对应的UnboundMethod?
如果你想拿到refine的方法对象,有几种方式:
- 直接从它的定义模块获取:
Module.instance_method(:refine) - 从Object的方法绑定中解绑:
Object.method(:refine).unbind - 专门查找私有实例方法:
Object.singleton_class.private_instance_method(:refine)
内容的提问来源于stack exchange,提问作者Kenta Nakajima
相关产品推荐
相关产品推荐

