gpt4 book ai didi

ruby - 单例对象上的 attr_accessor 未按预期工作

转载 作者:太空宇宙 更新时间:2023-11-03 16:14:40 28 4
gpt4 key购买 nike

为什么 Cat.new.name工作但Dog.new.name鉴于这两种不同的实现,不起作用:

class Cat
end

Cat.instance_eval do
attr_accessor :name
end

但这不起作用:

class Dog
class << self
attr_accessor :name
end
end

注意:我知道 Dog.name 工作,但我认为这两种实现都会导致创建 namename= Dog 的所有实例化的方法和 Cat .


问题背景:

开始:以下面的代码为例:

class Cat
end

Cat.instance_eval do
attr_accessor :name
end

c = Cat.new
c.name = 'some cat name'
p c.name # => "some cat name"

关于 ruby documentation of instance_eval ,我会讨论那个 instance_eval使用以下内容阻止:

  • 我们处于 Cat 的上下文中( Catself ),所以本质上,我们调用 Cat.attr_accessor :name ,这是一个宏,表示“嘿,对于从 Cat 创建的所有实例,为它们提供方法 namename=

我试图将这种理解扩展到以下内容,但它出错了:

class Dog
class << self
attr_accessor :name
end
end

d = Dog.new
d.name = "dog name" # => undefined method `name=' for #<Dog:0x007ff6c3062c20> (NoMethodError)

说到这里,我会说 class << self是说:

  • 将我置于Dog 的单例对象的上下文中, 所以 self现在是 Dog 的单例对象
  • 调用attr_accessor Dog 的单例对象上的宏(所以我们真的在调用 <singleton_of_Dog>.attr_accessor :name )。现在每次我们实例化一个 Dog对象,每个狗对象现在都有 namename= .

错误很明显是我这里的思路不对,但是我不确定我漏掉了哪一部分。

我搜索了以前的堆栈溢出问题,阅读了书籍并观看了解释 ruby​​ 对象模型的视频。不过,显然有一些我还没有完全掌握的基本概念。

最佳答案

class << self 的典型用法是创建一个 block ,其中实例方法被定义为类方法。这使您可以跳过输入 self.在方法定义中,还使其他设施可用,如私有(private)/ protected 。

它的工作原理是打开 Dog 的单例类并向其添加实例方法。 Dog 的单例类的实例方法成为 Dog 的类方法。这只是单例类定义的一部分。

在 attr_accessor 的情况下,这是您在 Dog 的类范围内调用的方法,它定义了 Dog 的实例方法。

当您在 Dog 的单例类上调用 attr_accessor 时,它会在 Dog 的单例类上创建实例方法。 Dog 的单例类的实例方法成为 Dog 的类方法。这就是为什么你可以使用 Dog.name =而不是 Dog.new.name =用你的代码。

关于ruby - 单例对象上的 attr_accessor 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49033323/

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