- 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