'String#reverse'如何返回非''String'对象?

时间:2017-11-14 22:29:33

标签: ruby equality return-type

我有一个班级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)wyWord,并且相等,因此它们都具有相同的方法,例如magicy在哪里获得magic方法?

3)当y == wtrue返回不等值时,y.s如何评估w.s

1 个答案:

答案 0 :(得分:7)

String#reverse的文档指出:

  

以相反的顺序返回一个带有str字符的新字符串。

因此您可能希望返回类型为String,如果您弹出方法,则可以看到该行

rev = rb_str_new_with_class(str, 0, RSTRING_LEN(str));

并且rev实际上是返回的。我的C相当生疏,但环顾C代码以寻找ruby,那个方法rb_str_new_with_class似乎完全正如它所说的那样,它创建了一个类str的新实例,在这种情况下{ {1}}。因此,当文档说它返回一个新字符串时,文档的含义是,它返回该字符串所属的任何类的新实例,在大多数情况下为Word

因此,知道它创建了当前字符串所在的任何类的新实例,很容易看出String最终如何使用w.reverse方法......因为magic给了它方法,它是Word

最后,他们如何平等?您没有在Word上定义新的==方法,因此它采用父String#==方法,该方法不知道或不关心有实例变量,只是比较值字符串,如果必要且能够使用Word强制执行,您甚至可以这样做:

to_str

(注意:我确实不确定Word.new("level") == "level" # => true 是否被胁迫。)