为什么实例在Ruby中没有'Class'作为父类?

时间:2014-06-03 16:22:14

标签: ruby

p 'a'.class.ancestors #=> [String, Comparable, Object, Kernel, BasicObject]
p String.class.ancestors #=> [Class, Module, Object, Kernel, BasicObject]

假设我在'a'上调用方法。它首先在String类中查找该对象,如果它在那里找不到它,它会在Comparable等中查找。

现在如果我在Class类上调用一个方法,它首先进入'Class',然后是'Module'等。

我不明白这是什么。为什么,当我在类似'a'的字符串实例上调用方法时,它不会查找'Class'中的方法?为什么'a'在其祖先列表中没有Class?

1 个答案:

答案 0 :(得分:4)

由于'a'不是class'a'string,因此'a'class {{的实例1}}。 StringString,因此它是class class的一个实例。

请记住这一点,Class Class的祖先。 StringClass的{​​{1}}。

当您在class上调用方法时,ruby将尝试在String的班级'a'及其祖先中找到该方法,其中没有一个是'a'

更多讨论

通常情况下,当我们没有进行这样的抽象讨论时,您会说StringClass,或'a'String。但这可能会导致当前背景下的混乱。

这是因为当前上下文中的String关系可能意味着至少两个不同的事情。 Classis a可能意味着对象x是类Y的实例,或者它可能意味着类x继承自类{{1} }}。 (当然命名约定会建议Y是一个对象而x是一个类......但那些不够实用)

这种Y关系的含糊不清是这里混乱的根源。因为在ruby中,所有类都是对象,类型为x的对象。为了使整个情况既令人困惑又优雅,Y也是一个对象! ...类型is a !!

Class

因此,如果我们只是简单地谈谈Class关系。 Class[7] pry(main)> 'a'.ancestors NoMethodError: undefined method `ancestors' for "a":String from (pry):7:in `__pry__' [8] pry(main)> 'a'.class.ancestors => [String, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject] [9] pry(main)> String.ancestors => [String, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject] [10] pry(main)> String.class.ancestors => [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject] [11] pry(main)> Class.ancestors => [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject] [12] pry(main)> Class.class.ancestors => [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject] is aString。但Class不会从String继承,而是Comparable的实例。 String不是Class的实例,它继承自Class

现在是刷新继承自关系含义的好时机。 String继承自Comparable,这意味着Comparable类型的所有对象也将继承类String中的行为。由于Comparable不会从String继承,因此Comparable类型的对象实例不会继承类String中的任何行为。

回到“是一种”关系。 ClassString。现在这适用于两种关系。 Class肯定继承自String。但ObjectString是一个实例,继承自Object。因此String也继承了类对象的行为。因此,当我们说ObjectClass时,它可能意味着其中任何一个。虽然,如果我们谈论继承,我们可能会说“StringString”,这意味着类Object的实例也是对象。虽然说“String是一个Object”(注意我放弃了文章“a”),但我们的意思是类String本身就是一个对象。

我刚刚意识到了别的什么。还记得我们如何在Ruby中声明静态方法? Ruby on rails - Static method

你说......

String

如果您考虑一下,使用关键字Object,我们就是指String的对象性质。因此,当您稍后调用class X def self.static_method ... end end 时,您将作为对象访问self并引用与对象X关联的实例方法。

希望我没有太多困扰你们。