読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

Object#freeze

Ruby

Object#freezeで、インスタンスの変更(インスタンス変数の変更)を禁止できます。

class Kitten
  def name
    @name
  end
  def name=(name)
    @name = name
  end
end

mii = Kitten.new
mii.name = "mii"

#凍結。
mii.freeze
#凍結後はインスタンス変数を変更できない。
mii.name = "mii"

実行結果です。

test.rb:7:in `name=': can't modify frozen object (TypeError)
    from test.rb:17

↓のように明示的にチェックしないとだめなのかと思っていたらそんなことはなかった。ふむ。

...
  def name=(name)
    raise "frozen." if frozen?
    @name = name
  end
...

ちなみに、Object#freezeでは、インスタンス再帰的な凍結はされないので注意。以下のような場合、Delegateインスタンスは凍結されますが、Delegateインスタンス変数「@delegate」は凍結されません。

class Delegate
  def initialize( delegate )
    @delegate = delegate
  end
  def method_missing(name, *args)
    @delegate.__send__( name, *args )
  end
  attr :delegate, true
end

mii = Delegate.new( Kitten.new )
mii.name = "mii"

#凍結。
mii.freeze

#Delegateのインスタンスは凍結されるが、
#Delegateのインスタンス変数「@delegate」は凍結されないため、変更が可能。
mii.name = "mii"