Umeyashikiの日記 RSSフィード Twitter

この日記は、こちらへ移転されました。 今後、このブログは更新しません。

2012年02月25日(土)

「達人プログラマー」を読んだけどいまいちわからなかった人へ - 「良いコードを書く技術」を読んだ。

【送料無料】良いコ-ドを書く技術

【送料無料】良いコ-ドを書く技術
価格:2,394円(税込、送料別)

プログラマーであれば誰でも良いコードを書きたい、良いプログラマーでありたいと思うはず。そんな人達がまず手にするのは名著「達人プログラマー」だろう。だけれど、あの本はある程度の経験が無いと理解できないところがあり、初心者向けという本ではない。

それに対して、「良いコードを書く技術」は初心者の視点が含まれているので、。

本書において、良いコードとは

  1. 保守のしやすいこと
  2. 動作が効率的であること
  3. 動作が正確であること
  4. 簡潔であること

の4つを条件としている。

現場で初めてプログラミングを学んだ人は、納期を気にするあまり、「(とりあえず)動くコードを書く技術 ]

が高くなりがちだと思う。そうすると、上の4つの条件はないがしろになり、最終的には、

  • 動作が効率的でなく、正確でないので手を入れたい
  • しかし、簡潔でなく、保守性がないので、手をつけられない。

という悪循環に陥る危険性がある。そういった経験をする初心者の立場を中心に書かれており、良いコードを書けるようになるためには何にこころがけるべきなのかが書かれている。

また、初心者だけでなく、中級者や上級者にとっても、自分の経験と照らし合わせてみて、再度、良いコードとは何なのかを考えられる。そして、「達人プログラマー」一度読んだことがある人にとっては、その内容を振り返る素材として良いと思う。

また、本書は新人教育にも使えるようにと書かれているので、これから入ってくるプログラミング未経験者に「良い本はないか?」と聞かれたら、これを紹介しようかと思います。

良いコードを書く技術は、一朝一夕では身につかず、常に習慣として心がけないといけない。

参考

2012年02月19日(日)

TDD != テストファースト - テスト駆動開発入門を読んだ。

【送料無料】テスト駆動開発入門

【送料無料】テスト駆動開発入門
価格:3,150円(税込、送料別)

2010年の初めからテストコードを真面目に書くようになって、「テストコードをはじめに書き、それを満たすために開発する」ことをテスト駆動開発と思っていた。ところが、RSpecの本とかを見たりはしていたけど、BDD*1を知っていることが前提だったりで、いまいちテスト駆動開発というものを明確に理解できていなかった。

ということで、ケント・ベックテスト駆動開発入門を読みました。

この本によれば、テスト駆動開発とは、

  1. ソフトウェア開発における不安を緩和することが目的であり、
  2. そして単なる開発ということだけでなく設計をも含んでいる

開発手法のこと。

1つ目は、今ままでテストコードを回帰テストのために書いたときに常に感じている。

自分が加えた変更が別の機能に影響していないか、そもそも期待している変更になっているのか、をちゃんとテストが教えてくれる。

そして、テストコードの記述は、新しい変更のために何をすればいいのか考える際の動力になる。これが2つ目の設計という言葉に相当するだろう。

本書では、これら基本的なことだけでなく、実際にどのように開発を進めていくのか、 Javaのサンプルコードを実例にあげて説明している。最期に、その実例の中で使ったパターンのまとめが説明されている。Javaの実例では、複数の通貨をとりあつかうクラスが、テストコードによってどのように抽象化され、一般化されていくかが見れて非常にわかりやすい。テストをグリーン*2を維持しつづけながらテストがリファクタリングされていく過程は非常に参考になった。自分の場合、レッドにした状態からグリーンにし、リファクタリングでは最終的にグリーンになればいいとしか思っていなかった。

そこで使われていたパターンについては、Javaに限らずどの言語でもテスト駆動開発一般に使えるものなので、今まで野良TDDやってきた人には考えの整理に役立つのではないでしょうか。

パターンだけ知りたい、という方は、それだけをまとめてくださっている方がいるので、そちらを参考に。

あと、テスト駆動開発をどうやって導入するかについても書かれているので、これから現場で始めたいという方にも役立ちそうです。

個人的には、勝手にテストコード書いてしまえばいい、という考えなのですが、ちゃんと上司などに説明しなければならない人に良さそうです。

参考

*1:Behavior Driven Development, 振る舞い駆動開発

*2:テストコードによるテスト結果が正しいこと。逆はレッド。

2012年01月29日(日)

homebrewでPostgreSQLインストールが失敗した時の対応

herokuで動くアプリケーションを開発しようとして、brewPostgreSQLインストールしようとしたところ、

$ brew install postgresql
(中略)
Undefined symbols:
  "_BIO_clear_flags", referenced from:
      _my_sock_read in be-secure.o
  "_BIO_set_flags", referenced from:
      _my_sock_write in be-secure.o
      _my_sock_read in be-secure.o
  "_SSL_CTX_set_info_callback", referenced from:
      _secure_open_server in be-secure.o
ld: symbol(s) not found
(中略)
Error: Failed executing: make install-world 
These existing issues may help you:
    https://github.com/mxcl/homebrew/issues/9217
Otherwise, please report the bug:
    https://github.com/mxcl/homebrew/wiki/checklist-before-filing-a-new-issue

とエラーが出て、インストールできなかった。

最後に指示されているように、homebrewのPull Requestを見に行くと

For the chaps that may want to do the same thing, I'm offering a few lines providing a "--build32" flag for postgresql and ossp-uuid.

とあり、どうやらpostgresqlとossp-uuidのインストール時のフラグが適切でないようだ。

そこで、上のPull Requestに書かれているパッチを充ててみる。

パッチ充ては、brew edit で行った。

$ brew edit postgresql 
$ brew edit ossp-uuid

とすると、エディタで該当のインストールスクリプトが開かれるので、修正して保存する。

で、今度は、

$ brew install postgresql --32-bit

インストールとしても、ダメでした…

そこで、エラーの原因である"_BIO_clear_flags"などが未定義であることについて調査したところ、Subversionで起きた同様の問題の解決方法を書いた記事を見つけました。

ということで、最終的に、brew edit postgresql で、48行目の条件文を

     if not ARGV.include? '--32-bit' and MacOS.prefer_64_bit? and not ARGV.include? '--no-python'

として、その条件文の後に下記を追加しました。

    if ARGV.include? '--32-bit'
      ENV.append 'CFLAGS', '-arch i386' 
      ENV.append 'LDFLAGS', '-arch i386' 
      # The following setup, refer to http://d.hatena.ne.jp/elim/20110501/1304221908
      ENV.append 'LDFLAGS', '-L/usr/local/Cellar/openssl/0.9.8r/lib'
      ENV.append 'CPPFLAGS', '-I/usr/local/Cellar/openssl/0.9.8r/include'
    end 

そして、再度

$ brew install postgresql --32-bit

としたところ、インストール成功しました*1

参考

*1:ただ、今回、2つの対応を入れてしまったので、どちらが有効だったのかは検証していません。

2012年01月20日(金)

「アジャイルサムライ 達人開発者への道」

【送料無料】アジャイルサムライ

【送料無料】アジャイルサムライ
価格:2,730円(税込、送料別)

昨年の楽天テクノロジーカンファレンスでテクノロジーアワードを受賞した、書籍「アジャイル開発 達人開発者への道」を読みました。

本書の構成としては、アジャイル開発とはどういったものなのか、計画と見積もり、そして立てた計画をプロダクト開発につなげていくためのプラクティスの説明で構成されています。「アジャイル開発について知りたい」人というよりかは、取り入れたい人にとってはとても分かりやすい内容と感じました。

本書を読んでいる中で常に感じるのが、アジャイル開発におけるプラクティスは決まった規則や形式はなく、その都度、プロジェクトに適したものへカスタマイズしていく必要がある、ということでした。この思想が「非ウォーターフォール」、つまりアジャイル開発には決まった形はないことということを教えられた気がします。

さて、アジャイル開発を取り入れるというのはなかなか難しいこと、と私は思っています。以前、あるプロジェクトでアジャイルを実践するつもりが、なかなかそうはいかなかったからです。それは、我々が採用したプラクティスを自分たちに合った形にカスタマイズしなかったせいだったことが原因だったと思っています。カスタマイズせずにプラクティスを実践し、不満を溜め込んだせいでプラクティスが信頼できなくなり、破綻したと推測しています。アジャイル初心者集団であったため、「プラクティス=これを実践すれば万事解決する銀の弾丸」といった盲信していました。

その盲信を捨てるために、本書に出てくる「マスターセンセイ」が必要なのではないでしょうか。「マスターセンセイ」は本書の中で、アジャイルプラクティスをマスターしており、アジャイルをこれから実践する者に対して、適切に助言をくれる存在として出てきます。実際に問題に直面したときに、「ここでマスターセンセイならばどうするのか?」と自問自答することができれば、変化を取り入れることが容易になるのではないでしょうか。

これからアジャイル開発を実践したい人にとって、くじけそうになった時の道しるべとして「マスターセンセイ」との対話をする場として、本書は役立つのではないでしょうか。

参考

2012年01月17日(火)

pebbles-dajare-0.1.0 is released! 駄洒落を自動生成するRubyGemをリリースしました。

ダジャレを自動生成するgemをこの度、リリースいたしました。

どうやって自動生成しているのかは、ソースを覗いてやってください。

まだ文字を使ったダジャレの生成なので、音をもじったダジャレ生成ができるように改善していきたいと思いますだおかだ

意味もなくDonationを募ってみたり、Travis CIビルドしてみたりと、お遊びではりますが、今後も頑張って開発を継続していきたいと思い益若つばさ

インストール方法

gem install pebbles-dajare

使い方

require 'pebbles/dajare'

Pebbles::Dajare.generate_dajare 'おはようございます' #=> おはようござい益若つばさ
'おはようございます'.dajarize #=> おはようござい益若つばさ

参考

2012年01月15日(日)

RSpecで標準入力を扱う処理のテストを書く

先日、会社の人に、

標準入力からユーザに文字列を入力してもらう処理のテストをどう書くのかわからない。

と聞かれた。

それまでやってみたことなかったのだけど、とりあえず思いつきでやってみたら出来たので、ここで公開してみる。

しかし、標準入出力は、getsとputsで行うものという前提です。

例として、

ユーザが入力した文字列を保存し、endという文字列が入力されたら処理を終了するメソッド

を実装するためのテストを書いてみました。

テストコード

require 'hoge'

describe Hoge do
  context "#input" do
    context "if entering two words until entering 'end'," do
      before do
        @hoge = Hoge.new
        @hoge.stub(:gets).and_return(*%w[foo bar end])
      end
      it "should print 'saved' twice" do
        @hoge.should_receive(:puts).with("start").once
        @hoge.should_receive(:puts).with("saved").twice
        @hoge.input
      end
      it "saved words should be the two words only, without 'end'" do
        @hoge.input
        @hoge.saved_words.should == %w[foo bar]
      end
    end
  end
end

ポイントは、単にgetsまたはputsと書いたときにself.getsと呼ばれることを利用すること。

試しに実装したもの

class Hoge
  def initialize
    @saved_words = []
  end

  def input
    puts 'start'
    while (w = gets.chomp) != 'end'
      puts 'saved'
      @saved_words << w
    end
  end

  def saved_words
    @saved_words
  end
end

テストの実行

rspecコマンドを実行すると、

$ rspec -cfd

Hoge
  #input
    if entering two words until entering 'end',
      should print 'saved' twice
start
saved
saved
      saved words should be the two words only, without 'end'

Finished in 0.00232 seconds
2 examples, 0 failures

1つ目と2つ目のexampleの間に、「start」と「saved」が2回出力されているのは、2つ目のexampleではputsをモックにしていないためです。

このテストの書き方の問題

上述のように、getsやputsでの標準入出力にしか対応していないことです。つまり、

STDOUT.puts "hoge"

といった出力には対応していません。

この問題の厄介なところは、実装の変更に応じて、その都度テストを書きなおす必要が発生するということです。普通であれば、テストはそのままにして、実装の修正に問題ないか確認しますが、それができません。

もっと一般的な標準入出力のテストの書き方ってないのだろうか。

参考

上の例であげたコードはgistでも公開しています。

2012年01月08日(日)

今年1年の抱負

今年も1週間が過ぎ、喪が明けた*1ので、気持ちを新たにし、今年の抱負を書き起こしたいと思います。

その前に昨年を振り返ってみると、公私ともに変化の年だったように思います。

  • 入社して初めての部署異動
  • 第2子の誕生

この変化は、それまでに無い新しいことへの挑戦を与えてくれました。

また、昨年は変化を起こそうとした年でもありました。

「会社の文化をより楽しいものにしたい」という考えのもと、色々と行動を起こしました。文化を変えるということは、挑戦する前から難しいこととは思っていたものの、その予想以上に難しいことを実感しました。ですが、何も変化が起こらなかったかというと、そうでもありませんでした。

同じように文化を変えたいという仲間を見つけられました。一人ではないと思えるようになり、色々な挑戦ができました。このことは、素晴らしいことと思っています。

今年の抱負は、「現実化」です。

昨年は、変化を起こすための行動に着手し、少し進んだ程度で、「変化が起きた」とはなかなか言えない状況でした。そこで、今年は昨年に積み上げてきたものを形にすることをやっていきたいと思います。

なんか、ぼやかしたような書き方をしてしまいましたが、短い時間で書き起こすために具体的な中身を端折っちゃいました。後で自分が見返してわかる程度に、ということで。

それでは、今年もよろしくおねがいいたします。

*1:まだ明けてはいないのですが、正月は過ぎたので。