読者です 読者をやめる 読者になる 読者になる

メッセージングによる代入

代入をメッセージングで表すことを考えてみる。

代入は、左辺に識別子をとり右辺に値をとる等式で表現できる。

ident = value

つまり代入とは、識別子というオブジェクトに "=" というメッセージセンドを行っていると解釈できる。Rubyで実装してみる。

#!/usr/bin/env ruby

class Identifier
  def initialize(name)
    @name = name
  end

  def ==(that)
    @value = that
  end
end

Identifier.new("ident") == "value"

Rubyでは "=" という名前のメソッドは定義できないので "==" で代用した。

では、識別子が Identifier のインスタンスだとすると、初期化されていない識別子の検出はどうすればいいのか。

まず、未定義をあらわす値 Undef を導入する。また、識別子の値は Undef で初期化されるべきだ。そして、識別子は初期化される際にグローバルなハッシュテーブルに名前と値の組を追加する。プログラムの実行終了時に値が Undef である Identifier のインスタンスが存在した場合、例外を投げる。

#!/usr/bin/env ruby

BEGIN {
  $ID_MAP = {}
}

class Undef; end

class Identifier
  def initialize(name)
    @name = name
    @value = Undef
    $ID_MAP.store(@name, @value)
  end

  def ==(that)
    @value = that
  end
end

END {
  uninitialized = $ID_MAP.select {|ident, value| value == Undef }
  uninitialized.each do |ident, value|
    raise NameError
  end
}

ここで一旦