[ruby-list:50844] Stringの派生オブジェクトにsubを取った時のインスタンス変数のコピー

From: Takefumi URA <ura.takefumi@...>
Date: 2019-11-21 16:55:42 UTC
List: ruby-list #50844
浦といいます。

Stringを派生させたクラスのオブジェクトにインスタンス変数を設定しました。
このオブジェクトにsubを適用してできたオブジェクトにはそのインスタンス
変数がコピーされていませんでした。以下のような感じです。


$ cat test-string.rb
class NString < String
  def initialize(s)
    @var = s.hash # ハッシュ値を取ってるのは特に意味はない
    super s
  end

  def inspect
    "#<NString:#{@var}:#{self}>"
  end
end

ns = NString.new('abc')
p ns                            # => #<NString:val:abc>
p ns.sub(/a/, 'A')              # => #<NString::Abc>

$ ruby -v test-string.rb
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]
#<NString:3775343761872790250:abc>
test-string.rb:8: warning: instance variable @var not initialized
#<NString::Abc>

ご覧の通り @var が引き継がれておらず初期化もなされていません。
このあたり、インスタンス変数もケアしてくれる (subでcloneなりdupなりやってる) 
のかなと思っていたので少し意外でした。

Stringのソースを見てないのでなんともなんですけど、
subを取って新たなオブジェクトが得られた時 @var の値をコピーするにはどうしたらよいでしょうか?

別解としてsub!を使ってそもそもコピーする必要をなくすというのはあるでしょうけど 
(というかそれでとりあえず解決しました)、純粋に疑問に思ったので質問してみることにしました。

In This Thread

Prev Next