騒がしい未来

サッカーやインターネット、旅行、日々のお仕事など、普段思ったことををつらつらと書いていく、高須正和のブログサイトです。 さいきんはtwitterばかり。

いよいよ最終回。今日のテーマはデバッグです!

 

■Rubyにおけるデバッグの特色…
 Rubyは型のない言語で、スクリプト言語なのでコンパイルもない。
なので、コンパイル時の型チェックによってバグが見つかることも無い。

 ただし、Rubyのオブジェクトには型があり、これが実行時にバグを発見する大きな手がかりになっている。Rubyには他言語のような自動型変換があまり無く、型が異なるオブジェクト同士の計算はエラーになる場合が多い。

 型がない言語の割に、バグが多いわけでもないのは、前回発表されたテストや、今回発表されるような豊富なデバッグツールで、バグを少なくする工夫がいくつもあるから。

とくに、書いてる最中にprintf やpなどを送り込めば、その場で出力ができるのはとても手軽。
型によってバグを減らすのではなく、バグの修正をしやすくすることにより品質を上げようというものがRubyの文化です。

——————-
トリビア..printf
これは Rubyの関数名だが、C の同名、ほぼ同機能の関数がオリジナル。Cのデバッグで本体コードにprintf を埋め込むことが多かったことに由来。
Rubyでは printf ではなく、p や puts を使うことが多い。
——————-

例:
>> 1 + “1″
TypeError: String can’t be coerced into Fixnum
    from (irb):1:in `+’
    from (irb):1
>> 1 + “1″.to_i
=> 2
>> 1.to_s + “1″
=> “11″

■デバッグ実演
Rubyに標準で付属するデバッガを使う場合など
最初にプログラムのブレークポイントを設定して、プログラムを途中まで走らせるようにし、ステップ実行ができるようにします。
しかし、普段はデバッガを使う必要はありません。
たいがいはprint -f で足ります。
というか「print -fで実行できないようなコードは書くな!」
(複雑で終えないようなものを作るのはRubyらしくない)

——————-
トリビア..Rubyの開発環境

そもそも統合開発環境があまりないこともあって、正直、デバッグ自体はJavaとEclipseのほうがやりやすい。統合開発環境としてはNetBeansが最近有名だが、さほど普及していない。
またはemacsやvi上で開発支援ツールを使うことになる。

自動でリファクタしてくれるツールもあるが、値や型名が変わって、setされることが多いRubyでは、どういう修正が加えられるのかわからず、怖くて使えない。EmacsやViは、今開いているウィンドウの中(Emacsは開いている複数のウィンドウ)だけで補完をしようという考え方
——————-

ユニットテストを使うようになると、そもそもデバッガの出番は減ってくる。プログラムをもっと細かく して、常々ユニットテストするようになると、デバッガを使わなくてもバグを追いかけられるようになる。

テストをテストするコードはないので、重複しようがなんだろうが、テストコードはあとで読めてバグが入り込まないように、ダラダラと長く書いたほうがよい。

参考URL
JUnit 実践講座 -
プログラミングスタイルガイド
http://www.morijp.com/masarl/homepage3.nifty.com/masarl/article/junit/programming-style-guide.html
(JavaのJUnitだが、基本は同じ)

RSpecという、仕様書を書くかのようにテストを実行するツールもあります。
http://jp.rubyist.net/magazine/?0021-Rspec

みんなでテストコードを書きましょう!

 

■デバッグのやりかたについて

Ruby Debugで検索するといくつかサイトが出てきます。

特にこのサイト
Ruby で debug する7つの方法 - 川o・-・)<2nd life
http://d.hatena.ne.jp/secondlife/20061010/1160453355
のデバッグのやりかたは参考になります。

ppというコマンドがあり、デバッグ時の出力を見やすくしてくれます。
べったり表示するのではなく、見やすくインデントして表示してくれます。

実行中に表示する値についてもp callerで実行すると、それぞれの値について、どういうメソッドを経由して到着したかがわかり、追いやすくなっています。

set trace_funcで実行すれば、プログラム内のすべての関数をtraceつきで実行してくれるので、非常に詳細に追いかけることができます。

railsではloggerの実行もあるていど準備されていて、使いやすくなっています。

また、profilerを実行すると、どのメソッドが何回呼ばれたか、それぞれの実行時間などがわかるので、高速化のチューニングに役立ちます。

 

■先週紹介できなかった、テストに使うメソッドassert_selectの補足

assert_select
テストの成功条件をCSSのセレクタの構文を使って簡単に記述することができるので、これまで難しかったviewのテストが簡単にできる。

Railsでのプログラミングは、基本的に一人ですべてのコード(本体もテストも)書くことが前提となっている。

——————-

以下、テストの方法についての議論が続きました。

 テストドリブン開発方法の功罪とか、
 仕様理解とテストの役割とか、
 グループで開発する際のテストの役割とか、
 テストコードは誰が書くべきか
 (プロジェクトマネージャーか、プログラム書いた本人か、
  テスターかなど)

■JRuby
オマケとして、普段Javaを使っている人のために、JRubyを紹介しました。
JRubyは、JVM上で動作しますが、Rubyと同じインタプリタでコンパイル不要、
文法もRubyそのものです。そしてJavaのライブラリをそのまま使うことができ
ます。サンプルとして、Javaで書かれたオープンソース検索エンジン Lucene
のインデックスを生成するスクリプトを紹介しました。

感想:
 ・テストのことを気にしたことがなかったので、いい刺激になりました。

 ・やっぱり勉強会面白いですね!
  来週からはまた、テーマを決めて勉強する会をやりますのでよろしく。
  (来週はインフラの予定)

 ・いい刺激になりました。時間がない中、なんだかんだ発表の準備を作るのすごいですね。

 ・ゲストとして勉強会に参加していたのですが、自分たちでもやってみたいです。
  こういう勉強会を成立させるのは何がキーなのか、それをかんがえさせられました。

 ・講師としては、教わっていてはまったく役に立たないのですが、教えるとムチャクチャ
  役に立ちます。
  輪講形式を取るのですが、全員が講師をするときにはいろいろ問題があります。
  講師になる人の負担はかなり大きいので、初心者には厳しかったかもしれない。
  もちろんその分勉強になったと思うが。