在matz的书“Ruby Programming Language”中,他说:
我们已经说过Ruby中的所有值都是对象,所有对象都是 由参考操纵。但是,在参考实现中, Fixnum和Symbol对象实际上是“立即值”而不是 引用。这两个类都没有mutator方法,所以Fixnum 和Symbol对象是不可变的......唯一的实际区别 立即值和参考值之间是立即值 不能在它们上定义单例方法。
所以我发布了irb并测试了这个声明。
class Symbol
def self.mutator
puts 'mutator method'
end
end
Symbol.mutator
# => mutator method
我刚刚在Symbol上定义了一个单例方法,没有错误。那么他在说什么呢?
答案 0 :(得分:4)
[...]立即值不能在它们上定义单例方法
Singleton方法是您在类实例的对象上定义的方法,而不是在类(对象)本身上定义的方法,就像您提供的示例一样。
请考虑以下代码:
s = :sym
def s.my_method
puts "HELLO"
end
# => TypeError: can't define singleton
在其他对象上时,例如string
:
str = "string"
def str.my_method
puts "HELLO"
end
str.my_method
# => HELLO
第二个没有任何错误。
希望有所帮助!
更新 - 什么是直接值
Fixnum是包含直接值的对象
这意味着什么?这意味着如果我们写x = 5,数字5将 直接存储(编码)到变量x中,如果它是a 原始数据类型(使用ruby传统对象,x会有 包含与存储在堆中的对象相对应的地址。 因此,当我们写x = 5时,x知道它需要的所有数字 事实上,x是对象,而不是对它的引用。
让我们考虑一个例子:
fix1 = 2
fix2 = 2
fix1.object_id
# => 5
fix2.object_id
# => 5
可是:
str1 = "test"
str2 = "test"
str1.object_id
# => 2157416420
str2.object_id
# => 2157531060
具有相同值的 Fixnum
具有完全相同的object_id
(同样适用于Symbol
),但String
s,即使它们是相似的值"test"
,它们具有不同的object_id
s。
因为立即值是不可变的(在内存中分配相同的位置),所以它们不可变。