- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
为什么 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
会 工作,但我认为这两种实现都会导致创建 name
和 name=
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
的上下文中( Cat
是 self
),所以本质上,我们调用 Cat.attr_accessor :name
,这是一个宏,表示“嘿,对于从 Cat
创建的所有实例,为它们提供方法 name
和 name=
。我试图将这种理解扩展到以下内容,但它出错了:
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
对象,每个狗对象现在都有 name
和 name=
.错误很明显是我这里的思路不对,但是我不确定我漏掉了哪一部分。
我搜索了以前的堆栈溢出问题,阅读了书籍并观看了解释 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/
我正在我的程序中设置一些跟踪代码,想知道哪些方法是通过attr_accessor 定义的。使用 TracePoint,我可以检测何时调用 attr_accessor,但我不知道如何让它告诉我它收到的参
我正在使用 data_mapper/sinatra 并尝试使用 attr_accessor 创建一些属性。以下示例代码: require 'json' class Person include D
我有父类,还有一些子类 class Base end class ChildNameAge < Base ATTRIBUTES = [:name, :age] attr_accessor *A
我想限制子类中父类(super class)方法的访问 class Parent attr_accessor :first_name, :last_name def initialize(fi
我想知道如何即时创建 attr_accessor。是否可以做类似的事情: attr_accessor "@#{key}" 在初始化方法中? module Mymodule def initiali
我不明白为什么我们需要在类中声明 attr_reader 和 attr_writer,或 attr_accessor。我都读了 this和 this帖子,但这些帖子主要解释它们是如何工作的,而不是它们
我有一个 attr_accessor 设置如下的类: class Human ATTRIBUTES = [:name] attr_accessor *ATTRIBUTES end 它就
我正在尝试创建一个包含 Singleton 的类使用 attr_accessor 时的模块。但这似乎不起作用。 require 'singleton' class Foo attr_accesso
我知道 Ruby 支持调用方法的简写风格,即:1.+(2) 与 1+2 相同(我仍然认为如果它与我的情况有关),但我真的很困惑为什么 attr_accessor 方法既不重复(好吧,它们不应该重复,因
http://gist.github.com/172341 (stackoverflow 破坏了格式) 在以下情况下,Human 创建的方法名称对 Boy 不可用。我的理解是否正确,attr_acce
我想使用 attr_accessor 将数组作为实例变量。 但是 attr_accessor 不只是用于字符串吗? 如何在阵列上使用它? 更新: 例如。如果你想: object.array = "ca
我正在尝试在 initialize 中执行一个 instance_eval,然后执行一个 attr_accessor,并且我一直得到这个:``initialize':未定义的方法“attr_acces
我在我的类中动态创建了一个实例变量: class Mine attr_accessor :some_var def intialize @some_var = true end
attr_accessor 不适用于以下代码。错误显示“父级未定义方法‘事物’(NoMethodError)”: class Parent @@things = [] attr_accesso
我理解 x |= y 基本上意味着 x = x|y。运算符 | 为类 Set 定义为计算两个集合的并集。确实我们可以看到: require 'set' r = Set.new(%w(a b)); s
我不明白为什么要这样写: class Building < ActiveRecord::Base attr_accessor :has_child_custom, 'test' end 然后我
我有一个简单的类,并且正在转置一个二维数组,如下所示: class Group attr_accessor :group_array def initialize @group_arr
我有一个简单的类,并且正在转置一个二维数组,如下所示: class Group attr_accessor :group_array def initialize @group_arr
这可能与 this question 完全相反.考虑以下规范: describe Record do it "calculates the first term grade" do tes
我正在使用 Sinatra 和 RSpec。我在 lib/auth.rb 中有这个 class Person attr_accessor :password if ENV['RACK_ENV'
我是一名优秀的程序员,十分优秀!