对Ruby中的对象感到困惑

3 ruby

Ruby新手在这里,

我知道一切都是Ruby中的一个对象,我不确定的一件事是理解Variables.变量基本上给出了对象的参考(如果我错了,请纠正我).在教学视频中,老师做了一个演示,如下所示:

(IRB)

a = 100
==> 100
b = a
==> 100
b
==> 100
Run Code Online (Sandbox Code Playgroud)

我得到的这部分,完全有道理.

然后他做到了

a = 50
==> 50
b
==> 100
Run Code Online (Sandbox Code Playgroud)

如果B应该指向一个100的设置,为什么如果a现在设置为50,b仍然指向100?

小智 9

这是很酷的东西,100也是一个对象.所以a指向常量对象100,当你指定b = a你分配b给指向对象的指针而100不是指针,a或者甚至是100的值a.

要看到这是真的,试试这个:

irb> puts 100.object_id
=> 201
Run Code Online (Sandbox Code Playgroud)

好吧?

这里是我前一段时间写过的Ruby对象模型的一个小解释.它不是特定于您的问题,而是增加了一些关于Ruby对象模型如何工作的知识:

当你创建一个对象的实例时,你创建的是一个新对象,它有一组实例变量和一个指向对象类的指针(以及一些其他的东西,比如对象ID和指向超类的指针)但是方法本身不在对象的实例中.类定义包含方法列表及其代码(以及指向其自己的类的指针,指向其超类的指针和对象ID).

当您在实例上调用方法时,Ruby会查找实例的类,并在该类的方法列表中查找您调用的方法.如果找不到它,那么它会在类的超类中查找.如果它没有在那里找到它,它会查看该类的超类,直到它用完超类.然后它返回到第一个类并查找method_missing方法.如果没有找到它,那么它会进入超类,依此类推,直到它到达设计为引发错误的根对象.

比方说,你有一个Person类,你用变量bubba创建一个类的实例,如下所示:

class Person
  attr_accessor :dob, :name
  def age
    years = Time.now.year - @dob.year
    puts "You are #{years} year#{"s" if years != 1} old"
  end
  def feed
    puts "nom, nom, nom"
  end
end
bubba = Person.new
bubba.name = "Bubba"
bubba.dob = Time.new(1983,9,26)
Run Code Online (Sandbox Code Playgroud)

类图看起来像这样: 替代文字

那么在创建静态方法,类/模块方法时会发生什么?好吧,请记住,几乎所有东西都是Ruby中的对象,模块定义是类Class的一个实例.是的,你输入的代码实际上也是一个实例,它是实时代码.使用def self.method_name创建类方法时,您将在对象的实例中创建一个方法,该方法是类/模块定义.

太好了,那么你所要求的类方法在哪里?它是在一个匿名类(也就是单例,特征,鬼类)中定义的,正是出于这个原因而创建的.

回到我们的Person类,如果我们在实例bubba上添加类方法,如下所示:

def bubba.drive_pickup
  puts "Yee-haw!"
end
Run Code Online (Sandbox Code Playgroud)

该方法被放入一个专为该实例创建的特殊单例类中,而单例的超类现在是Person类.这使我们的方法调用链看起来像这样: 替代文字

在实例对象bubba上定义的任何其他方法也将被放入该单例类中.每个实例对象永远不会有多个单例类.

因此,为了解决这一问题的原因,模块中的静态方法是在单例类中为模块定义的实例定义的.当您从模块中包含或扩展时,您将添加指向模块的方法表的指针,但不添加模块的单例类的实例对象的方法表.

可以这样想:如果你创建一个类型为Z的实例x和一个类型为Z的实例y,那么x应该知道y吗?不,除非特别说明,否则不会.在另一个模块中混合的模块也不应该知道其他一些恰好将第一个模块作为其超类的对象.

为了更好地解释Ruby对象模型,观看这个令人敬畏的免费视频,由令人惊讶的博学的Dave Thomas(不,不是来自Wendy的人):http:
//scotland-on-rails.s3.amazonaws.com/2A04_DaveThomas-SOR .MP4

观看视频后,我从Pragmatic 购买了Dave Thomas 关于Ruby对象模型的全系列文章,这非常值得.

PS任何人都可以随意纠正我忘记的任何事情; 就像对象中的具体内容一样.