Ruby中对象的singleton_class为何不是Class?is_a?返回false的困惑
问题解答
核心误区在于对is_a?方法的理解:它是用来判断一个对象是否是某个类(或其子类)的实例,而不是判断该对象(这里是单例类)的祖先链中是否包含这个类。
你获取的singleton是obj的单例类,它本质上是Class类的实例(Ruby中所有类都是Class的实例),而不是Animal类的实例。所以调用singleton.is_a?(Animal)时,Ruby在检查这个单例类对象本身是不是Animal的实例——显然不是,因此返回false。
那单例类祖先链里的Animal代表什么?单例类的超类就是它所属对象的类(也就是Animal),所以singleton.ancestors会包含Animal,但这是单例类自身的继承关系,和is_a?负责的实例归属检查是完全不同的两个维度。
如果要验证单例类的继承链中是否包含Animal,应该用这两种方式:
singleton < Animal # 返回true,判断单例类是否是Animal的子类 # 或者 singleton.ancestors.include?(Animal) # 返回true,直接检查祖先链
而如果是要判断原对象obj是否是Animal的实例,直接调用obj.is_a?(Animal)就会返回true,这才是is_a?的正确使用场景。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

