What is it, naokirin?

はじめてのRuby&RSpec

TDDBC福岡でRubyRSpecを用いたTDDを見て、かなり興味が湧きまして、そして少し触ってみることにしました。元々、「次にWebアプリ系を触るときはRubyをやる!」という気持ちはあったので、これも何かの縁と思ってやりました。

1日触ったくらいですが、RSpecユニットテストフレームワークというより、BDD(Behavior Driven Development, 振る舞い駆動開発)のフレームワークと言った方がしっくりくる感じがしました。(単純にそのように感じたというだけです。テストというより振る舞いを決めている、という感じが強かったからでしょうか)。

今回の課題は某日経ソフトウェアという雑誌の課題から拝借しまして行いました。ちなみにその某雑誌の方ではC(かC++)で解答がついています。私は見てませんが(笑)

課題内容ですが、36進数を10進数にする、というもの。

今回はそれをRuby&RSpecで挑戦しました。

base36_spec.rb

require 'base36'

def trans_spec(name, actual, expected)
  context name do
    subject { Base36.new(actual).decimal }
    it { should == expected }
  end
end

describe Base36 do
    trans_spec("with z", "z", 35)
    trans_spec("with 10", "10", 36)
    trans_spec("with aaaa", "aaaa", 479890)
    trans_spec("with Z", "Z", 35)
    trans_spec("with _", "_", -1)
end

base36.rb

class Base36
  def initialize(str)
    @strData = str
  end

  def digitToDecimal(chr)
    if chr =~ /\d+/ then
      return chr.to_i
    elsif chr =~ /[a-z]/ then
      return chr.bytes.to_a[0] - "a".bytes.to_a[0] + 10
    elsif chr =~ /[A-Z]/ then
      return chr.bytes.to_a[0] - "A".bytes.to_a[0] + 10
    else
      return -1
    end
  end

  def decimal()
    strArray = @strData.split(//)
    i, retnum = 1, 0
    for str in strArray do
      if digitToDecimal(str) < 0 then
        return -1
      else
        retnum += digitToDecimal(str) * (36**(strArray.length - i))
        i += 1
      end
    end
    return retnum
  end
end

テストコード側はかなり重複除去を進めています。実装側のコードのリファクタリングが足りない気もします。パラメタライズドテストみたくなったのは気のせいだと思います。重複を除去しようと頑張った結果です。
仕様として記号などの文字が入っていた場合に-1を返すようにしているのがあまり好きではないです。また、ASCII文字以外の文字が入っていた場合は完全にエラーという処理になります。このあたりも対処法があるのであれば直したいところです。

Ruby自体にも慣れていないのでこのコードを書くだけで随分と時間をとってしまいました。実際にはRubyに標準で任意の基数への変換のメソッドが存在するので今回のコードは練習用でしかないです。

Rubyの書き方というものに慣れていないので、微妙なコードになっている気がしてなりません。いわゆる「動くけど…」という状態です。このあたりは他の人のよいコードを見ながら学んでいくしかなさそうです。

今回Rubyを始めて、Ruby自体の感想としては今回のコードでも用いましたが、Rubyの簡単に行える正規表現の判定はすごく便利でした。このあたりはWebアプリやスクリプトでは重宝しそうです。

ちなみに今回のコードを書くにあたり、Ruby入門Rubyist Magazineid:t-wadaさんのRSpec の入門とその一歩先へは大変参考になりました。とくにid:t-wadaさんのRSpecの解説は丁寧で初心者でもRubyist Magazineの記事を読んでいるだけでRSpecの初歩が分かるように書かれています。また私はまだRailsを全く触っていないので何とも言えませんが、Rubyist Magazineの記事にはRSpec on Railsも書かれています(というよりは基本的にそれが主)。Railsをやっている方も参考になると思います。ぜひ、RSpec初心者の方はこの2つの記事は参考にしてみてください。