Posted by
okkez
Wed, 18 Jun 2008 08:10:00 GMT
日本Rubyの会 公式Wiki - 第27回 Ruby/Rails勉強会@関西
もうすぐ開催されます。
今回はかずひこさんも久しぶりに登壇しますので、すごく楽しみです。
お時間のある方は、上記URIに申し込み方法が書いてあるので、そちらを参照の上、参加申し込みしてくださいね。
Posted in Ruby |
コメントはありません |
Posted by
okkez
Thu, 12 Jun 2008 07:52:00 GMT
Posted in Ruby |
コメントはありません |
Posted by
okkez
Tue, 15 Apr 2008 13:58:00 GMT
Overview — Phusion Passenger (a.k.a. mod_rails)
思ったより簡単だったのでちょっとだけ手順を書いておく。
- Apache は 2.2 系
- Rails2.0.2
- Redmine0.7.0RC1
上記はインストールできている and 動作確認できている前提で。
まずは、Passenger をインストール。
sudo gem install passenger
で以下のコマンドを実行。
passenger-install-apache2-module
そうすると対話型っぽい感じになって色々と親切に教えてくれる。足りないライブラリとそれらの入手方法とか。
個人的にはもう少し不親切でもいいような気がした。
このコマンドではApacheのモジュールをビルドするので Windows ではかなり苦労するであろう事が予想される。(調べてないけど)
最後に、httpd.conf に書く設定内容が表示されるのでそれをコピペして Apache を再起動すればOK。
各アプリの設定は後で書く。
もう一つのインストール方法でやる場合は、ソースを展開したディレクトリの下にビルドしてインストールされてしまうので、ちょっと気持ち悪い。手でコピーすればいいけどコマンドが動的に生成されるっぽいのでその辺の調整が必要。
### Redmine を使う
- /var/webapps/redmine に置いている
- /var/www/html が Apache の DocumentRoot
サブドメインが使える場合は以下でOK。
ServerName redmine.example.com
DocumentRoot /var/webapps/redmine/public
サブドメインが使えない場合(素朴なイントラネットなど)。
ln -s /var/webapps/redmine/public /var/www/html/redmine
のようにシンボリックリンクを DocumentRoot 以下に用意する。
で、以下の内容を httpd.conf を追加する。
DocumentRoot /var/www/html
RailsBaseURI /redmine
サブドメインが使える場合は NameBase の VirtualHost でいくらでもアプリケーションを置くことができるが、そうでない場合は以下のようにすればいけるかもしれない。(まだ試してない)
RailsBaseURI /redmine1
RailsBaseURI /redmine2
考えてみたけど VirtualHost を使用せずに一つのアプリに別々のRailsEnv を設置する方法がわからない。
上のやり方だと、一つの環境しか設定できないような気がするし。
以上の設定内容は全部、 Passenger のサイトに書いてあった。最初からドキュメントが揃っているのは素晴らしい!
Posted in Ruby |
コメントはありません |
Posted by
okkez
Fri, 22 Feb 2008 15:04:00 GMT
ざっとこんなもんかな。時間ある時に勝手に添削する。
# 添削希望のものだけね。
Kanasan の 100 マス計算
趣味も大分入るけど以下のような感じで添削しました。
- 題意を勘違いしてる?
- 演算子もランダムにして欲しかったけどこれはこれでアリなので活かすことにする
- 使える演算子は決まっているので、定数化する
- 入力値のチェックに正規表現を使っていたがこの程度なら文字列比較で十分
- 一度初期化したら変わらない変数は定数にする
- メソッド定義のカッコは省略しない
- exit 1 にしとく
- コマンドの失敗時の戻り値は 1 であることが多いため
- 一文字変数はスコープが短い所で使用する
- 配列の変数名は配列であることが予想できるような名前にする
kanasan's 100マス計算添削後
#! /usr/bin/ruby
OPERATORS = %w[+ - * / %]
DIGIT = 2
SEPARATOR = " "
VERTICAL_LINE = "|"
HORIZONTAL_LINE = "-"
CROSS_LINE = "+"
operator = ARGV[0].to_s
unless OPERATORS.include?(operator)
puts "wrong parameter: operator is only +-*/%"
exit 1
end
def display100Math(xs, ys, operator, display_answer)
print SEPARATOR * (DIGIT - operator.size)
print operator
print SEPARATOR
print VERTICAL_LINE
xs.to_a.each do |x|
print SEPARATOR
print SEPARATOR * (DIGIT - x.to_s.size)
print x
end
puts ""
print HORIZONTAL_LINE * DIGIT
print HORIZONTAL_LINE
print CROSS_LINE
xs.size.times do
print HORIZONTAL_LINE
print HORIZONTAL_LINE * DIGIT
end
puts ""
ys.each do |y|
print SEPARATOR * (DIGIT - y.to_s.size)
print y
print SEPARATOR
print VERTICAL_LINE
if display_answer
xs.each do |x|
answer = y.send(operator, x)
print SEPARATOR
print SEPARATOR * (DIGIT - answer.to_s.size)
print answer
end
end
puts ""
end
end
xs = (1..9).sort_by{rand}
ys = (1..9).sort_by{rand}
display100Math(xs, ys, operator, false)
puts ""
display100Math(xs, ys, operator, true)
やらなかったこと
sixeight さんの 100 マス計算
同じく趣味が入るけどこんな感じ。
- いくつかの変数名/メソッド名を変更した
- initialize に仕事積めすぎなので @header を make_question に移動
- そうするとインスタンス変数である必要がなくなるのでローカル変数にした
- make_matrix は表作成専用にした
適切に仕事を分割することでよりよくなったはず。
sixeight's 100 マス計算添削後
class Hyakumasu
def initialize
@op = [:+, :-, :*, :/][rand(4)]
@row = (0..9).sort_by{ rand }
@col = (0..9).sort_by{ rand }
end
def make_matrix
header = "#{@op} | " + @col.join(' ') + "\n--|" + "---" * @col.length
@row.inject(header){|r, v|
r + "\n#{v} |" + (block_given? ? yield(v) : '')
}
end
def display
puts make_matrix
puts
puts make_matrix{|v|
@row.map {|i|
"%3d" %((@op == :/ && i.zero?) ? 0 : v.send(@op, i))
}.join
}
end
end
Hyakumasu.new.display
Posted in Programming, Ruby |
コメントはありません |
Posted by
okkez
Sun, 17 Feb 2008 13:56:00 GMT
いつも通りみんなの集合時間より早く行って簡単な打ち合わせ。
日本Rubyの会 公式Wiki - 第23回 Ruby/Rails勉強会@関西
Ruby1.9 の仕様 − Array 関連の新しい機能 by こなみ さん
よくも悪くも講義?って感じだった。
最後の方の内容が面白かっただけに尻切れとんぼっぽくなったのが残念。
純粋関数型言語Ruby(3) 30分でわかるMonad by 氏久(ujihisa)さん
やっぱり 30min ではわからなかった Monad
参加者大半おいてけぼり??
Rails以外のWebアプリケーションフレームワーク」 by yhara さん
merb, capmping, ramaze の紹介。前二つはストヤン経由で聞いてたけど結局試してなくてごめんなさい。
今度、試す。
Rubyのリフレクション by 大林さん
おもしろかった。久しぶりに燃えるセッションだった。
# って自分こんなにリフレクション好きだったっけ?
すごく勉強になった。要復習。
これくらいの濃さのセッションが毎回あるといいのだけど。
Ruby初級者向けレッスン第17回 by okkezさん
自分のセッション。
初級者レッスンと言いつつ、るりまの宣伝乙。
演習問題もリファレンスを見てやってもらう前提だったのでこんなものかと。
演習問題の最後に、使うかもしれないメソッド一覧を載せたのは良かったらしい。Keep
そう言えば、自分が発表する場合の時間の読み方がかなり正確になってきた気がする。
Posted in Ruby |
コメントはありません |
Posted by
okkez
Wed, 23 Jan 2008 13:18:00 GMT
Ruby には暦週を求める Date#cweek というメソッドがあるが、こいつは月曜日スタートで日曜日で終わる。
でも、たまに日曜日から土曜日での暦週が欲しくなることがある。というか今日必要になった。
なので作ってみた。
class Date
def myweek
if wday == 0
(self + 3).cweek
# cweek + 1 でいいかも。。。
else
cweek
end
end
end
とりあえず試した範囲では上手く動いてた。
Posted in Ruby |
コメントはありません |
Posted by
okkez
Sun, 04 Nov 2007 03:22:00 GMT
Test::Unit版
と同じことを RSpec でやってみた。
第 20 回 Ruby 勉強会@関西
に解答例(answer.pdf)がアップされていますがそれの捕捉説明的なものです。前回と同様、配布資料(print.pdf)が手元にある前提で進めます。
Test::Unit 版とは書いた時期が違うので微妙に実装が違っていたりします。
ちなみに RSpec を使って書くのは初めてです。RSpec についてはるびまの記事を参照してください。
なお、stack_spec.rb は、そのとき注目している機能に関係のある部分のみ掲載します。
実装するメソッド
- empty?
- スタックが空なら true、そうでなければ false を返す。
- size
- push(val)
- pop
- スタックの一番上の値を取り除いて返す。スタックが空の場合は Stack::EmptyStackErrorが発生する。
Step1
- Stack#empty? のテスト
- 「新しいスタックの empty? は真」
stack_spec.rb
require 'stack'
describe Stack, "when empty" do
before do
@empty_stack = Stack.new
end
it "should be empty" do
@empty_stack.should be_empty
end
after do
@empty_stack = nil
end
end
Stack が空のときの動作を記述。
- spec -c で実行すると色つきで結果が表示される
stack.rb
class Stack
def empty?
true
end
end
- とりあえず Test::Unit 版と同じように Fake it してみた
Step2
- Stack#push と Stack#pop のテスト
- 「新しいスタックに 3 を push して pop すると 3 が返る」
stack_spec.rb
describe Stack, "when push 3" do
before do
@stack = Stack.new
@stack.push(3)
end
it "should pop 3" do
@stack.pop.should == 3
end
after do
@stack = nil
end
end
- describe の引数に書いた内容を before のブロックに記述する
- it 〜 end に実際にチェックしたい内容を記述する
- after のブロックに後始末の処理を記述する
- before と after は省略可能
stack.rb
class Stack
def empty?
true
end
def push(val)
end
def pop
3
end
end
- Test::Unit 版と同じように Fake it
Step3
- Stack#size のテスト
- 「新しいスタックに 3 を push すると size は 1」
stack_spec.rb
describe Stack, "when push 3" do
before do
@stack = Stack.new
@stack.push(3)
end
it "should pop 3" do
@stack.pop.should == 3
end
it "should size 1" do
@stack.size.should == 1
end
after do
@stack = nil
end
end
- Step2 と事前準備の内容は同じなので同じ describe ブロック内に it 〜 end を追加する
stack.rb
class Stack
def empty?
true
end
def push(val)
end
def pop
3
end
def size
1
end
end
Step4
- Stack#size のテスト (2)
- 「新しいスタックに 3 を push すると size は 1」
- 「さらに 5 を push すると size は 2」
stack_spec.rb
describe Stack, "when push 3 and 5" do
before do
@stack = Stack.new
@stack.push(3)
@stack.push(5)
end
it "should size 2" do
@stack.size.should == 2
end
end
- 前のステップとは状況が違うので新しい describe ブロックを用意した
stack.rb
class Stack
def initialize
@size = 0
end
def empty?
true
end
def push(val)
@size += 1
end
def pop
3
end
def size
@size
end
end
- Fake it のままでは通らないので、ちょっとまじめに実装。
Step5
- Stack#empty? のテスト (2)
- 「新しいスタックに 3 を push すると empty? は偽」
stack_spec.rb
describe Stack, "when push 3" do
before do
@stack = Stack.new
@stack.push(3)
end
it "should pop 3" do
@stack.pop.should == 3
end
it "should size 1" do
@stack.size.should == 1
end
it "should not be empty" do
@stack.should_not be_empty
end
after do
@stack = nil
end
end
- 事前準備の状況が Step2, Step3 と同じなので同じ describe に振舞を追加
stack.rb
class Stack
def initialize
@size = 0
end
def empty?
size == 0
end
def push(val)
@size += 1
end
def pop
3
end
def size
@size
end
end
Step6
- Stack#pop のテスト (2)
- 「新しいスタックを pop すると Stack::EmptyStackError が発生する」
stack_spec.rb
describe Stack, "when empty" do
before do
@empty_stack = Stack.new
end
it "should be empty" do
@empty_stack.should be_empty
end
it "should raise Stack::EmptyStackError" do
lambda{
@empty_stack.pop
}.should raise_error Stack::EmptyStackError
end
after do
@empty_stack = nil
end
end
stack.rb
class Stack
class EmptyStackError < StandardError
end
def initialize
@size = 0
end
def empty?
size == 0
end
def push(val)
@size += 1
end
def pop
raise EmptyStackError if empty?
3
end
def size
@size
end
end
Step7
- Stack#pop のテスト (3)
- 「新しいスタックに 3 を push して 5 を push して pop すると size は 1」
stack_spec.rb
describe Stack, "when push 3 and 5, then pop" do
before do
@stack = Stack.new
@stack.push(3)
@stack.push(5)
@stack.pop
end
it "should size 1" do
@stack.size.should == 1
end
after do
@stack = nil
end
end
stack.rb
class Stack
class EmptyStackError < StandardError
end
def initialize
@size = 0
end
def empty?
size == 0
end
def push(val)
@size += 1
end
def pop
raise EmptyStackError if empty?
@size -= 1
3
end
def size
@size
end
end
Step8
- Stack#pop のテスト (4)
- 「新しいスタックに 3 を push して 5 を pushして pop すると 5 が返る」
stack_spec.rb
describe Stack, "when push 3 and 5" do
before do
@stack = Stack.new
@stack.push(3)
@stack.push(5)
end
it "should size 2" do
@stack.size.should == 2
end
it "should pop 5" do
@stack.pop.should == 5
end
after do
@stack = nil
end
end
stack.rb
class Stack
class EmptyStackError < StandardError
end
def initialize
@size = 0
@stack = []
end
def empty?
size == 0
end
def push(val)
@size += 1
@stack.push(val)
end
def pop
raise EmptyStackError if empty?
@size -= 1
@stack.pop
end
def size
@size
end
end
Step9
最後にリファクタリングします。
stack_spec.rb
require 'stack'
describe Stack, "when empty" do
before do
@empty_stack = Stack.new
end
it "should be empty" do
@empty_stack.should be_empty
end
it "should raise Stack::EmptyStackError" do
lambda{
@empty_stack.pop
}.should raise_error Stack::EmptyStackError
end
after do
@empty_stack = nil
end
end
describe Stack, "when push 3" do
before do
@stack = Stack.new
@stack.push(3)
end
it "should pop 3" do
@stack.pop.should == 3
end
it "should size 1" do
@stack.size.should == 1
end
it "should not be enpty" do
@stack.should_not be_empty
end
after do
@stack = nil
end
end
describe Stack, "when push 3 and 5" do
before do
@stack = Stack.new
@stack.push(3)
@stack.push(5)
end
it "should size 2" do
@stack.size.should == 2
end
it "should pop 5" do
@stack.pop.should == 5
end
after do
@stack = nil
end
end
describe Stack, "when push 3 and 5, then pop" do
before do
@stack = Stack.new
@stack.push(3)
@stack.push(5)
@stack.pop
end
it "should size 1" do
@stack.size.should == 1
end
after do
@stack = nil
end
end
- 上記の仕様を満たすように実装コードを書き換えます。
- 本来はちょっとずつ書き換えるべきですが、最終結果のみ書いておきます
stack.rb
require 'forwardable'
class Stack
extend Forwardable
def_delegators(:@stack, :empty?, :push, :size)
def initialize
@stack = []
end
def pop
raise EmptyStackError if empty?
@stack.pop
end
class EmptyStackError < StandardError
end
end
- forwardable ライブラリを使用するとメソッドを指定して特定のオブジェクトに委譲できる
- 使用方法はリファレンスマニュアルを確認してください
Posted in Ruby |
コメントはありません |
Posted by
okkez
Fri, 02 Nov 2007 11:52:00 GMT
行ってきた。
第 20 回 Ruby 勉強会
内容は置いといて、初級者レッスンの解答例(answer.pdf)に補足説明を入れておく。
資料は上記サイトでダウンロードしてくださいな。
以下では、配布資料(print.pdf)が手元にあることを前提に進めていきます。
実装するメソッド
- empty?
- スタックが空なら true、そうでなければ false を返す。
- size
- push(val)
- pop
- スタックの一番上の値を取り除いて返す。
スタックが空の場合は Stack::EmptyStackErrorが発生する。
テスト駆動開発版
TDD でやってくのです。
Step1
- Stack#empty? のテスト
- 「新しいスタックの empty? は真」
ということなのでまずはテストを書きます。
test_stack.rb
require 'stack'
require 'test/unit'
class TestStack < Test::Unit::TestCase
def setup
@stack = Stack.new
end
def test_empty?
assert(@stack.empty?, 'a new stack is empty.')
end
end
空っぽのテストなので簡単ですね。
* Stack#empty? のテストをしたいのでテストメソッド名は test\_empty?
* assert は 第一引数の式が真で無い場合にに失敗する
で、実装。普通は失敗してから Fake it するのですが、print.pdfでは既に失敗してるのでここではいきなり成功しときます。
stack.rb
class Stack
def empty?
true
end
end
ここでは成功さえすれば良いのでいきなり true を返します。
#### Step2
* Stack#push と Stack#pop のテスト
* 「新しいスタックに 3 を push して pop すると 3 が返る」
まずテスト。
test_stack.rb
require 'stack'
require 'test/unit'
class TestStack < Test::Unit::TestCase
def setup
@stack = Stack.new
end
def test_empty?
assert(@stack.empty?, 'a new stack is empty.')
end
def test_push_and_pop
@stack.push(3)
assert_equal(3, @stack.pop, 'pop returns the last value.')
end
end
* Stack#push と Stack#pop のテストなのでテストメソッド名は test\_push\_and\_pop
stack.rb
class Stack
def empty?
true
end
def push(val)
end
def pop
return 3
end
end
* Stack#push はテストが通るので、まだ空っぽでいい。
* Stack#pop はテストを通すために 3 を返す。
明らかにテストが不足しているが、まだ書かない。一歩ずつ確実に進んで行く。
#### Step3
* Stack#size のテスト
* 「新しいスタックに 3 を push すると size は 1」
なにがなんでもまずテスト。
test_stack.rb
require 'stack'
require 'test/unit'
class TestStack < Test::Unit::TestCase
def setup
@stack = Stack.new
end
def test_empty?
assert(@stack.empty?, 'a new stack is empty.')
end
def test_push_and_pop
@stack.push(3)
assert_equal(3, @stack.pop, 'pop returns the last value.')
end
def test_push_and_size
@stack.push(3)
assert_equal(1, @stack.size, 'push increments the size.')
end
end
* push してから size を確認するのでテストメソッド名は test\_push\_and\_size
* まだ一個しか push しない
* 二個 push したらどうなる?とかこの段階では考えない。
stack.rb
class Stack
def empty?
true
end
def push(val)
end
def pop
return 3
end
def size
1
end
end
* 3 を push したら size が 1 になればいいのだから Stack#size は 1 を返せばいい
* しつこく Fake it
* テストを通すことだけ考える。
#### Step4
* Stack#size のテスト (2)
* 「新しいスタックに 3 を push すると size は 1」
* 「さらに 5 を push すると size は 2」
とりあえずテストを書いてみる。
test_stack.rb
require 'stack'
require 'test/unit'
class TestStack < Test::Unit::TestCase
def setup
@stack = Stack.new
end
def test_empty?
assert(@stack.empty?, 'a new stack is empty.')
end
def test_push_and_pop
@stack.push(3)
assert_equal(3, @stack.pop, 'pop returns the last value.')
end
def test_push_and_size
@stack.push(3)
assert_equal(1, @stack.size, 'push increments the size.')
@stack.push(5)
assert_equal(2, @stack.size, 'push increments the size.')
end
end
素直に書けばこうなるはず。
実装コード
stack.rb
class Stack
def initialize
@size = 0
end
def empty?
true
end
def push(val)
@size += 1
end
def pop
return 3
end
def size
return @size
end
end
* Fake it では通らなくなったので、マジメに実装。
* 放っておいても今のところ大丈夫な部分は放置。
#### Step5
* Stack#empty? のテスト (2)
* 「新しいスタックに 3 を push すると empty? は偽」
いつまでも Stack#empty? が true しか返さないのはまずいので、false を返す場合のテストを書いてみる。
test_stack.rb
require 'stack'
require 'test/unit'
class TestStack < Test::Unit::TestCase
def setup
@stack = Stack.new
end
def test_empty?
assert(@stack.empty?, 'a new stack is empty.')
end
def test_push_and_pop
@stack.push(3)
assert_equal(3, @stack.pop, 'pop returns the last value.')
end
def test_push_and_size
@stack.push(3)
assert_equal(1, @stack.size, 'push increments the size.')
@stack.push(5)
assert_equal(2, @stack.size, 'push increments the size.')
end
def test_push_and_empty?
@stack.push(3)
assert_equal(false, @stack.empty?, 'a stack with data is not empty.')
end
end
で、テストが失敗するのでテストが通るように実装コードを変更します。
stack.rb
class Stack
def initialize
@size = 0
end
def empty?
return @size == 0
end
def push(val)
@size += 1
end
def pop
return 3
end
def size
return @size
end
end
* @size == 0 が true/false のいずれかを返すので return します
* 関係ない部分は弄りません
#### Step6
* Stack#pop のテスト (2)
* 「新しいスタックを pop すると Stack::EmptyStackError が発生する」
誰がなんと言おうがテストコードを先に書きます。
test_stack.rb
require 'stack'
require 'test/unit'
class TestStack < Test::Unit::TestCase
def setup
@stack = Stack.new
end
def test_empty?
assert(@stack.empty?, 'a new stack is empty.')
end
def test_push_and_pop
@stack.push(3)
assert_equal(3, @stack.pop, 'pop returns the last value.')
end
def test_push_and_size
@stack.push(3)
assert_equal(1, @stack.size, 'push increments the size.')
@stack.push(5)
assert_equal(2, @stack.size, 'push increments the size.')
end
def test_push_and_empty?
@stack.push(3)
assert_equal(false, @stack.empty?, 'a stack with data is not empty.')
end
def test_empty_pop
assert_raise(Stack::EmptyStackError,
'to pop a empty stack raise an error.') {@stack.pop}
end
end
* 空のスタックに対して pop するのでテストメソッドは test\_empty\_pop
* assert_raise はブロックに例外が発生する可能性のある処理を記述する
実装コード
stack.rb
class Stack
class EmptyStackError < StandardError; end
def initialize
@size = 0
end
def empty?
return @size == 0
end
def push(val)
@size += 1
end
def pop
raise EmptyStackError if empty?
return 3
end
def size
return @size
end
end
* Stack#pop を修正。
* Stack#empty? が true の場合に例外を発生させる
* 関係ない部分は意地でも書き換えない
#### Step7
* Stack#pop のテスト (3)
* 「新しいスタックに 3 を push して 5 を push して pop すると size は 1」
例によってテストを先に書きましょう。
test_stack.rb
require 'stack'
require 'test/unit'
class TestStack < Test::Unit::TestCase
def setup
@stack = Stack.new
end
def test_empty?
assert(@stack.empty?, 'a new stack is empty.')
end
def test_push_and_pop
@stack.push(3)
assert_equal(3, @stack.pop, 'pop returns the last value.')
end
def test_push_and_size
@stack.push(3)
assert_equal(1, @stack.size, 'push increments the size.')
@stack.push(5)
assert_equal(2, @stack.size, 'push increments the size.')
end
def test_push_and_empty?
@stack.push(3)
assert_equal(false, @stack.empty?, 'a stack with data is not empty.')
end
def test_empty_pop
assert_raise(Stack::EmptyStackError,
'to pop a empty stack raise an error.') {@stack.pop}
end
def test_push_push_pop_and_size
@stack.push(3)
@stack.push(5)
@stack.pop
assert_equal(1, @stack.size, 'pop decrements the size.')
end
end
* テストメソッド名は test\_push\_push\_pop\_and\_size
* 特別なことはしていません
実装コード
stack.rb
class Stack
class EmptyStackError < StandardError; end
def initialize
@size = 0
end
def empty?
return @size == 0
end
def push(val)
@size += 1
end
def pop
raise EmptyStackError if empty?
@size -= 1
return 3
end
def size
return @size
end
end
* 関係ない部分は弄らない、と
#### Step8
* Stack#pop のテスト (4)
* 「新しいスタックに 3 を push して 5 を pushして pop すると 5 が返る」
そろそろ佳境ですが、テストを先に書きます。
test_stack.rb
require 'stack'
require 'test/unit'
class TestStack < Test::Unit::TestCase
def setup
@stack = Stack.new
end
def test_empty?
assert(@stack.empty?, 'a new stack is empty.')
end
def test_push_and_pop
@stack.push(3)
assert_equal(3, @stack.pop, 'pop returns the last value.')
end
def test_push_and_size
@stack.push(3)
assert_equal(1, @stack.size, 'push increments the size.')
@stack.push(5)
assert_equal(2, @stack.size, 'push increments the size.')
end
def test_push_and_empty?
@stack.push(3)
assert_equal(false, @stack.empty?, 'a stack with data is not empty.')
end
def test_empty_pop
assert_raise(Stack::EmptyStackError,
'to pop a empty stack raise an error.') {@stack.pop}
end
def test_push_push_pop_and_size
@stack.push(3)
@stack.push(5)
@stack.pop
assert_equal(1, @stack.size, 'pop decrements the size.')
end
def test_push_push_and_pop
@stack.push(3)
@stack.push(5)
assert_equal(5, @stack.pop, 'pop returns the last value.')
end
end
実装コード
stack.rb
class Stack
class EmptyStackError < StandardError; end
def initialize
@size = 0
@values = Array.new
end
def empty?
return @size == 0
end
def push(val)
@size += 1
@values[@size - 1] = val
end
def pop
raise EmptyStackError if empty?
val = @values[@size - 1]
@size -= 1
return val
end
def size
return @size
end
end
外から見た動作ではスタックぽく動くようになりましたね。
さて、 irb で中身を覗いてみましょう。
irb(main):001:0> load 'stack.rb'
=> true
irb(main):002:0> s = Stack.new
=> #
irb(main):003:0> s.push 1
=> 1
irb(main):004:0> s.push 2
=> 2
irb(main):005:0> s.push 3
=> 3
irb(main):006:0> s.inspect
=> "#"
irb(main):007:0> s.pop
=> 3
irb(main):008:0> s.pop
=> 2
irb(main):009:0> s.pop
=> 1
irb(main):010:0> s.inspect
=> "#"
irb(main):011:0>
@values の中身が Stack#pop しても消えませんね。これはスタックとしては拙いのでリファクタリングしましょう。
というわけで次回に続く。
Posted in Ruby |
コメントはありません |