フラットスコープの実験

id:metanest:20101108#1289201211 に書いたのはまずくて

foo = Counter.new 0
p foo.inc
p foo.inc
p foo.dec
p foo.dec
bar = Counter.new 100
p bar.inc
p bar.inc
p bar.dec
p bar.dec
p foo.inc
p foo.inc
p foo.dec
p foo.dec

を実行すると

$ ruby19 foo.rb
1
2
1
0
101
102
101
100
101
102
101
100

こうなる。bar を作るときに Counter#inc, Counter#dec を再定義してしまうので、foo のほうがそれに影響されて壊れてしまうわけだ
というわけで、特異クラスに定義するように修正

class Counter
	def initialize initval
		count = initval

		self.singleton_class.__send__(:define_method, :inc) {
			count += 1
		}

		self.singleton_class.__send__(:define_method, :dec) {
			count -= 1
		}
	end
end

こうなる

$ ruby19 foo.rb
1
2
1
0
101
102
101
100
1
2
1
0