NoMethodError 但是这个方法实际存储在哪里? 事实证明,Ruby 在幕后创建了一个新类(有时称为单例类、元类 或特征类),-6ren">
gpt4 book ai didi

ruby - 在 Ruby 中是否有语法 : class << self . .. end 的任何相关应用程序

转载 作者:数据小太阳 更新时间:2023-10-29 06:43:15 24 4
gpt4 key购买 nike

class << self
attr_accessor :n, :totalX, :totalY
end

上面的语法用于定义类实例变量。但是当我考虑语法意味着什么时,它对我没有任何意义,所以我想知道这种类型的语法是否用于任何其他类型的定义。我在这里的困惑点是:

class << self

附加运算符通常表示“将右侧的内容添加到左侧的对象”。但是在这个 block 的上下文中,这如何加起来“将这个 block 的内容放入类实例而不是实例的定义中”?

出于同样的原因,我很困惑为什么在一个上下文中类 << self 可以定义类实例变量,而在另一个上下文中它似乎创建类变量,如下所示:

class Point
# Instance methods go here
class << self
# Class methods go here
end
end

最佳答案

在 Ruby 中,您可以重新打开现有类并添加方法。也就是说,你可以说:

class Foo
def bob
return "hello from bob"
end
end

这些方法存储在 Foo 的内部字典(可能是实例变量)中的某处。 -class(它只是 Class -class 的一个实例,因此实例变量)

但令人惊讶的是,您还可以向现有对象的实例添加方法

foo = Foo.new
foo2 = Foo.new

def foo.fred
return "I am fred"
end


foo.fred #=> "I am fred"
foo2.fred #=> NoMethodError

但是这个方法实际存储在哪里

事实证明,Ruby 在幕后创建了一个新类(有时称为单例类元类特征类),它被插入到继承中Foo 之间的层次结构 -类及其实例。

所以继承关系看起来是这样的:

foo < (eigenclass of foo) < Foo < Class

(如果你说 foo.superclass 你将看不到单例类)

class << X -syntax 是进入这个特殊类的一种方式,这样你就可以直接操作它。以下代码块完全等效:

def foo.bar
return "xy"
end

# is exactly the same as

class << foo
def bar
return "xy"
end
end

所以 class Foo < Bar 之间的相似度和 class << Foo不是偶然的,两者都有继承。

想到class << X作为“打开 X 的元类”

在 Ruby 中要记住的一点是,类本身就是对象。 (类的实例 Class )所以如果你说:

class Foo
class << self
def k
return "x"
end
end
end

(self 在此代码块中绑定(bind)到 Foo)所以 kFoo 的特征类的实例方法 , 这使它成为 Foo 的类方法

所有这些在 chapter about classes of the Pickaxe 中都有更清楚的解释。 (不幸的是,网络版本不包含图表)和_whys Seeing Metaclasses Clearly

关于ruby - 在 Ruby 中是否有语法 : class << self . .. end 的任何相关应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/896480/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com