提问人:Tony Marshle 提问时间:11/15/2017 最后编辑:sawaTony Marshle 更新时间:11/15/2017 访问量:71
'String#reverse' 如何返回非 'String' 对象?
How can 'String#reverse' return non-'String' objects?
问:
我有一个班级:Word
class Word < String
end
w = Word.new("level")
y = w.reverse
y.class # => Word
1) 这怎么可能? 应该返回 ,因为它继承了 ,它返回一个 .Word#reverse
String
String#reverse
String
我添加了以下代码:
class Word < String
attr_accessor :s
def magic
@s = Time.now
end
end
y.magic
sleep(5)
w.magic
y.s == w # => false
y == w # => true
2) 和 是 和 相等,因此它们都具有相同的方法,例如 。从哪里获得该方法?w
y
Word
magic
y
magic
3) 为什么计算到 while 并返回不相等的值?y == w
true
y.s
w.s
答:
7赞
Simple Lime
11/15/2017
#1
虽然 String#reverse
的文档指出:
返回一个新字符串,其中包含 str 中的字符,顺序相反。
因此,您可能期望返回类型为 ,如果您弹出该方法,您可以看到以下行String
rev = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
这就是实际得到的回报。我的 C 相当生疏,但是环顾 ruby 的 C 代码,该方法似乎完全按照它所说的去做,它创建了任何类的新实例,在这种情况下。因此,当文档说它返回一个新字符串时,它的意思是它返回该字符串的任何类的新实例,在大多数情况下是 .rev
rb_str_new_with_class
str
Word
String
因此,知道它创建了当前字符串的任何类的新实例,很容易看出最终如何拥有一个方法......因为给了它方法,而且它是一个.w.reverse
magic
Word
Word
最后,它们如何相等?您没有在 上定义一个新方法,因此它采用父 String#==
方法,该方法不知道或不关心是否存在实例变量,只是比较字符串的值,在必要时强制使用,您甚至可以执行以下操作:==
Word
to_str
Word.new("level") == "level" # => true
(注意:我实际上不确定是否被胁迫。Word
评论