hitode909の日記

趣味はマリンスポーツですの日記です

inspectで自分自身のインンタンス生成を出力する

Rubyで,1とか,'hello'とか,{:foo => :bar}とかは,inspectした結果がソースコードと同じで,プログラムとして実行できる.
自分で作ったクラスなんかだと,#<クラス名> みたいな文字が出る.
普通のクラスでもinspectすると自分自身を作るようなコードが表示されるとおもしろい気がしたから作ってみた.

module PrintSelf
  def inspect
    args = self.method(:initialize).parameters.map{ |param|
      self.instance_variable_get("@#{param[1]}".to_sym).inspect
    }
    "#{self.class}.new(#{args.join(", ")})"
  end
end


class Human
  include PrintSelf
  def initialize(name, age)
    @name = name
    @age = age
  end
end

p Human.new('inoue', 13)


pするとこれが出る.

Human.new("inoue", 13)


inspectしてevalすると同じオブジェクトになったり,意味ないけど,何重にもevalとinspectを繰り返したりできる.

p eval(Human.new('inoue', 13).inspect)
p eval(eval(eval(eval(Human.new('inoue', 13).inspect).inspect).inspect).inspect)


initializeが定義されていて,引数が同じ名前のインスタンス変数にそのまま代入されているようなクラスでのみ使える.
ログに出てきたオブジェクトをコピーしてirbとかに貼ればオブジェクトができると便利な気がしたけど,そんなに便利じゃない気もする.
なんとなく自分を書き出すとおしゃれみたいな文化がある.


https://gist.github.com/1857903