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

Ton*_*hle 1 ruby equality return-type

我有一节课Word:

class Word < String
end

w = Word.new("level")
y = w.reverse
y.class # => Word
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

2)w并且yWord,并且是相同的,因此它们都具有相同的方法,例如magic.哪里y获得了这个magic方法?

3)如何来y == w评估为true消磨y.sw.s返回值的不平等?

Sim*_*ime 7

String#reverse国家文件:

以相反的顺序返回带有str字符的新字符串.

所以你可能期望一个返回类型String,如果你打开方法就可以看到该行

rev = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
Run Code Online (Sandbox Code Playgroud)

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

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

最后,他们如何平等?你没有定义一个新的==方法Word,所以它需要父String#==方法,它不知道或不关心有实例变量,只是比较字符串的值,to_str如果必要和能够强制使用,你甚至可以做:

Word.new("level") == "level" # => true
Run Code Online (Sandbox Code Playgroud)

(注意:我实际上不确定是否Word会被胁迫.)