自分のクラスの新しいインスタンスを作る方法

ツリーのようなデータ構造を作っていると,自分のクラスの新しいインスタンスを作りたくなる場合があります.私は最初,以下のようなコードを書いていました.

#!/usr/bin/ruby
require 'pp'

class TestClass
  attr_accessor :serial, :obj
  @@serial = 'id0000'
  def initialize
    self.serial = @@serial.succ!.dup
    self
  end

  def duplicate
    return TestClass.new
  end
end

s0 = TestClass.new
s0.obj = 'Hello'

s1 = s0.duplicate
s1.obj = 'World'

pp [[s0.serial, s0.obj],
    [s1.serial, s1.obj]]

実行例:

% ./selfclass-0.rb
[["id0001", "Hello"], ["id0002", "World"]]

duplicateメソッドで"TestClass.new"のように,自分のクラス名を直に書いているのがださいです.どうにかならないか,と,RubyのマニュアルでObjectクラスのメソッドを眺めていたところ,"Object#class"というメソッドを発見しました.これを使うと,以下のようにすっきり書くことができます.

#!/usr/bin/ruby
require 'pp'

class TestClass
  attr_accessor :serial, :obj
  @@serial = 'id0000'
  def initialize
    self.serial = @@serial.succ!.dup
    self
  end

  def duplicate
    return self.class.new
  end
end

s0 = TestClass.new
s0.obj = 'Hello'

s1 = s0.duplicate
s1.obj = 'World'

pp [[s0.serial, s0.obj],
    [s1.serial, s1.obj]]

実行例:

% ./selfclass-1.rb
[["id0001", "Hello"], ["id0002", "World"]]

Objectクラスは宝の山ですね.
また,自分のクラスのスーパクラスはself.class.superclassで参照することができるようです.スーパクラスのインスタンスを作成する場合は,self.class.superclass.newという感じでしょうか.