Prototype based OOP と Class based OOP

最後のkazuhoさんのコメントが

挙げられている例のようにテクニックを使えば、さまざまなことができます。C 言語でだって、オブジェクト指向のコードを書くことができます。
ではなぜ C++ が、オブジェクト指向の開発で使われるのでしょう? C よりも C++ のほうが OO するのに向いているからですよね。

同様の理由で、Prototype-based OO のほうが Class-based OO よりもメモリに優しいモデルである、と言えると私は考えています。

なわけだけど、RubyPython みたいな実行時にインスタンスやクラスの挙動を書き換えられる言語と比較したら Prototype based と Class based の本質的な違いって Syntax 以外にとくにないんじゃないかと思う。いやまぁ、Ruby なんかだとメソッドとは別にインスタンス変数を保持しなけりゃいけないからそりゃ多少メモリを食うだろうが、結局、メソッドとインスタンス変数のシンボルテーブルの切り方以上の問題ではなく、メソッドのディスパッチを言語レベルでサポートしてないC言語とは比べるべくも無いような。
そもそも、ランタイムにオブジェクトやスコープごとにシンボルテーブルを作るような言語処理系でメモリ効率言われてもなぁ、という気がしないでもない。
ところで、Ruby で method_missing を使って prototype っぽい挙動をさせようとすると以下のような感じでいいんだろうか。メソッドの場合は特異メソッド等で対処。メソッドのコピーとかできないけど。まぁ、ostruct.rb からパクって簡略化しただけだけどな。

class PrototypeBase
   def initialize(hash=nil)
      @table = {}
      if hash
         for k,v in hash
            @table[k.to_sym] = v
         end
      end
   end

   def prototype
      self.class::PROTOTYPE
   end

   def method_missing(mid, *args)
      mname = mid.id2name
      len = args.length

      if mname =~ /=$/
         if len != 1
            raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
         end
         mname.chop!
         @table[mname.intern] = args[0]
      elsif len == 0
         if @table.has_key? mid
            @table[mid]
         else
            prototype[mid]
         end
      else
         raise NoMethodError, "undefined method `#{mname}' for #{self}", caller(1)
      end
   end
end

class A < PrototypeBase
   PROTOTYPE = { :y => 20 }   
end

if $0 == __FILE__
   o = A.new
   o.x = 10
   puts o.x
   puts o.y
   o.y = 5
   puts o.y
   puts A.new.y
end