Ruby 如何';定义一种方法';在语义上工作? 背景:
以下是我对对象模型的理解(相对于我下面的问题):Ruby 如何';定义一种方法';在语义上工作? 背景:,ruby,class,object,methods,object-model,Ruby,Class,Object,Methods,Object Model,以下是我对对象模型的理解(相对于我下面的问题): self始终引用当前堆栈帧中的接收器 当您处于顶层并说def someMethod时,隐式接收器是self,您正在创建一个与self关联的匿名类中的方法。这个匿名类恰好位于对象的下方(self是对象类的一个实例),因此当您调用someMethod时,Ruby“向右迈出一步”,它进入匿名类,从而找到并调用您的方法 这类似于在类定义中定义方法时发生的情况。如果在类定义中,您说:def self.classMethod您正在一个匿名类中创建一个方法,
始终引用当前堆栈帧中的接收器李>self
- 当您处于顶层并说
时,隐式接收器是def someMethod
,您正在创建一个与self
关联的匿名类中的方法。这个匿名类恰好位于self
的下方(对象
是self
类的一个实例),因此当您调用对象
时,Ruby“向右迈出一步”,它进入匿名类,从而找到并调用您的方法李>someMethod
- 这类似于在类定义中定义方法时发生的情况。如果在类定义中,您说:
您正在一个匿名类中创建一个方法,该匿名类位于def self.classMethod
类的正下方。当前正在定义的类的“右侧”现有的此类的方法对于新类的实例将不可见李>class
我的问题: 首先“在类中定义方法”是如何发生的?(语义上)
Class
对象不应该与普通对象不同,对吗
从我对消息处理的理解来看,Class
对象有一个表作为其状态的一部分,这可能意味着它是一个实例变量,具有其所有实例方法的名称。这就是查找方法的工作原理。(如果Ruby找不到它,它会一次又一次地向上移动,可能到链上下一个链接的方向是当前类对象状态的一部分。)
由于Ruby并不真正关心对象类型,所以我认为它不关心在执行方法查找时是否特别在Class
对象中查找。更确切地说,它只是跟随引用并查找具有特定名称的状态位。那么,我是否可以创建自己的“类对象”,而不使用不从类继承的class关键字
如果这个问题没有任何意义,那么我道歉。我只想知道当解释器遇到def
关键字时会发生什么 在ruby中编写“def something”时,就是在向模块中添加一个方法。有时,该模块是一个“类”(模块的一种类型)。这完全取决于当时的“自我”是什么:
class Foo
# right now self is 'Foo'
class << self
# right now self is 'Class:Foo'
end
def self.bar
# right now self is 'Foo'
end
end
def Foo.buz
# right now self is 'Foo'
end
obj = Foo.new
def obj.baz
# right now self is 'Foo:0x007fe8a632fa78' (an instance)
end
方法分派处理继承链中存在的内容。它是父模块的列表(不是树),并根据创建继承的时间进行排序:
# bar.rb
module MixinA
def something
puts "MixinA"
super
end
end
module MixinB
def something
puts "MixinB"
end
end
class Base
def something
puts "Base"
super
end
end
class Sub < Base
include MixinB
include MixinA
def something
puts "Sub"
super
end
end
obj = Sub.new
obj.something
检查链条:
> Sub.ancestors
=> [Sub, MixinA, MixinB, Base, Object, Kernel, BasicObject]
当此列表中发生方法调用时,将查找有问题的方法。如果链中没有一个模块具有该方法,则搜索从顶部开始,而是调用方法\u missing。在任何一种情况下,找到的第一个解决方案都将获胜
Yehuda Katz在2009年写了一篇关于这方面的好文章:
不从类继承的类对象是什么?这不是其他物体吗?@DaveNewton是的。这就是为什么我用双引号引它。我问你是否可以创建一个行为类似于类
对象的普通对象,并隐含地问这样做会涉及到什么。。。。。同样,这只是为了理解“定义方法”的真正含义,您可以使用class.new(superclass=nil)创建类对象
如果您检查Class.new.Class.superclass
您可以确定Class
继承自-这是它获得大部分功能的地方。如果您真的想要,您很可能会扩展模块来创建类似类的对象。
# bar.rb
module MixinA
def something
puts "MixinA"
super
end
end
module MixinB
def something
puts "MixinB"
end
end
class Base
def something
puts "Base"
super
end
end
class Sub < Base
include MixinB
include MixinA
def something
puts "Sub"
super
end
end
obj = Sub.new
obj.something
$ ruby bar.rb
Sub
MixinA
MixinB
> Sub.ancestors
=> [Sub, MixinA, MixinB, Base, Object, Kernel, BasicObject]