- eXtreme Training -
2004/4/1 勝田 均
- [2004/7/10]Ruby1.8のTest::Unitを使うように直しました。
- [2004/6/6]関数名を少しRubyらしく直しました。
- [2004/4/4]コンパイルエラーという記述をエラーに訂正しました。また、assert_exceptionの使い方が間違っていたので訂正しました。
- ここでは,寺田雄一郎さんによる『エクストリーム・トレーニング』―『- eXtreme Training - Stack クラスの作成』の Ruby 移植版です。オリジナルは,上記サイトに有ります。
- 翔ソフトウェア の Fujiwo さんの C#版 を移植した部分もあります。
- C++やC#なら面白い部分でも、Rubyでどう扱っていいのかわからない部分はあっさり削ってしまいました。
- Rubyの標準の配列を使えばいいことは最初からわかりきっているので、実際にこのような手順でStackを実装することはないですが、TDDを理解する手助けにはなるでしょう。
テスト成功(OK)
テスト失敗(Failure)
エラー(Error)
require 'test/unit'
class StackTest < Test::Unit::TestCase
end
def Stack
end
class StackTest < Test::Unit::TestCase
def test_constructor
assert(false, "no implementation" )
end
end
require Stack' class StackTest < Test::Unit::TestCase def test_constructor assert(false, "no implementation" ) s = Stack.new assert( s.empty? ) end end
class Stack
def empty?
return true #仮実装
end
end
class StackTest < Test::Unit::TestCase
...
def test_push
assert(false, "no implementation" )
end
end
def test_push assert(false, "no implementation" ) s = Stack.new s.push( 3 ) assert( !s.empty? ) def
class Stack def empty? return true end def push( a ) end end
class Stack def initialize @empty = true end def empty? return true return @empty end def push( a ) @empty = false end end
def test_push
s = Stack.new
s.push( 3 )
assert( !s.empty? )
assert_equal( 3, s.top ) # top 関数がない
end
class Stack
...
def top
return 3 # 仮実装
end
end
def test_push s = Stack.new s.push( 3 ) assert( !s.empty? ) assert_equal( 3, s.top ) s.push( 8 ) assert_equal( 8, s.top ) end
class Stack def initialize @empty = true @value = nil end def push( a ) @empty = false @value = a end def top return 3 return @value end
def test_constructor
s = Stack.new
assert( s.empty? )
assert_equal( 0, s.size )
end
class Stack
...
def size
return 0 # 仮実装
end
end
def test_push
s = Stack.new
Stack& ref = s
s.push( 3 )
assert( !s.empty? )
assert_equal( 1, s.size )
assert_equal( 3, s.top )
assert_equal( 3, ref.top )
s.push( 8 )
assert_equal( 8, s.top )
assert_equal( 8, ref.top )
s.top = 10
assert_equal( 10, ref.top )
end
class Stack ... def size return 0 return @empty ? 0 : 1 # 仮実装 end ... end
def test_push
s = Stack.new
s.push( 3 )
assert( !s.empty? )
assert_equal( 1, s.size )
assert_equal( 3, s.top )
s.push( 8 )
assert_equal( 2, s.size )
assert_equal( 8, s.top )
end
class Stack def initialize @empty = true @value = nil @size = 0 end ... def Size return @empty ? 0 : 1 # 仮実装 return @size end def push( a ) @empty = false @value = a @size += 1 end ... end
class Stack def initialize @empty = true @value = nil @size = 0 end def empty? return @empty return @size == 0 end ... def push( a ) @empty = false @value = a @size += 1 end ... end
class StackTest < Test::Unit::TestCase
...
def test_pop
assert(false, "no implementation" )
end
end
def test_pop assert(false, "no implementation" ) s = Stack.new s.push( 3 ) s.pop assert( s.empty? ) assert_equal( 0, s.size ) end
class Stack
...
def pop
@size = 0 # 仮実装
end
...
end
def test_pop s = Stack.new s.push( 3 ) s.push( 5 ) s.pop assert_equal( 1, s.size ) s.pop assert( s.empty? ) assert_equal( 0, s.size ) end
class Stack ... def pop @size = 0 @size -= 1 end ... end
def test_pop
s = Stack.new
s.push( 3 )
s.push( 5 )
s.pop
assert_equal( 1, s.size )
assert_equal( 3, s.top )
s.pop
assert( s.empty? )
assert_equal( 0, s.size )
end
class Stack def initialize @value = nil @value = Array.new(2) @size = 0 end ... def push( a ) @value = a @values[@size] = a @size += 1 end ... def top return @value return @values[@size-1] end end
class Stack def initialize @values = Array.new(2) @size = 0 @values = [] end def empty? return @size == 0 return @values.empty? end def size return @size return @values.size end def push( a ) @values[@size] = a @size += 1 @values.push( a ) end def pop @size -= 1 @values.pop end def top return @values[@size-1] return @values.last end end
StackTest.rb
def test_constructor s = Stack.new assert( s.empty? ) assert_equal( 0, s.size ) ex = assert_raises( RuntimeError ) { s.top } assert_equal( "StackEmptyException", ex.message ) end
Stack.rb
def top
raise "StackEmptyException" if @values.empty?
return @values.last
end
StackTest.rb
def test_constructor s = Stack.new assert( s.empty? ) assert_equal( 0, s.size ) ex = assert_raises( RuntimeError ) { s.top } assert_equal( "StackEmptyException", ex.message ) ex = assert_raises( RuntimeError ) { s.pop } assert_equal( "StackEmptyException", ex.message ) assert_equal( 0, s.size ) end
Stack.rb
def pop
raise "StackEmptyException" if @values.empty?
@values.pop
end
Stack.rb
…リファクタリング…
class Stack … def pop raise "StackEmptyException" if @values.empty? empty_check @values.pop end def top raise "StackEmptyException" if @values.empty? empty_check return @values.last end def empty_check raise "StackEmptyException" if @values.empty? end end