.logbook

学んだことを書き綴る、言わば航海日誌です。

mrubyデバッガ(mrdb)を使ってみる

これは、ETロボコン Advent Calendar 2014 - Adventarの 24日目のエントリーです。

昨日の記事はyamane (@yuri_at_earth) | Twitterさんによるmrubyの記事でした。mrubyは個人的にもいろいろと関わりがあり、気に入っている言語です。

mrubyは随分前からオープンソースとして公開されていますが、まだ触ったことのない人が多いと思います。本記事ではmrubyの環境を(さくっと)構築して、mrubyを使う方法をまとめます。

また、mruby 1.1.0で登場したデバッガ(mrdb)の使い方をまとめます。

記事を書いていたところ、ボリュームが大きくなり過ぎてしまったため、2記事に分割しました。mrubyについてよく知らないという人は以下の記事も参照ください。

ETロボコン2015の準備。mrubyの開発環境を知る - .logbook

想定する環境

ETロボコン参加者はWindowscygwinで環境構築している人が多いと予想されるため、cygwin上でmrubyを使えるようにします。

Linux, Macでもほぼ同様の手順で環境構築できまず。

mrubyを使う準備をする

cygwin上で必要なツールをインストール

下記ツールをインストールします。setup-x86.exeまたはsetup-x86_64.exeを使用します。

  • gcc(必須)
  • make(必須)
  • ruby(必須)
  • bison(必須)
  • git(必須ではない)

それぞれ、cygwin上で取得できる最新バージョンを指定します。

gcc

f:id:ylgbk:20141221185330p:plain

make

f:id:ylgbk:20141221185342p:plain

ruby

f:id:ylgbk:20141221185353p:plain

bison

f:id:ylgbk:20141221185404p:plain

git

f:id:ylgbk:20141221185413p:plain

選択したら、インストールします。

mrubyの取得とビルド

githubからmrubyを取得してビルドしましょう。ビルド後は出来上がった実行ファイルを/cygwin/binへコピーします。以下のコマンドを順番に入力してください。

$ git clone https://github.com/mruby/mruby.git
$ cd mruby/
$ make
$ cp bin/* /bin

以上で環境の準備は完了です。

mrubyを実行しよう

環境が整ったら早速Rubyのソースを書いて、mrubyで実行しましょう。ソースのサンプルとしてFizzBuzzプログラムを作ってみました。(Rubyオブジェクト指向言語であることがわかるよう、あえてクラス化しています)

fizzbuzz.rb

class FizzBuzz
  FIZZ = 3
  BUZZ = 5

  def initialize
    @take = 0
  end

  def answer(max)
    @take = @take + 1
    print "take #{@take}----------\n"
    (1..max).each do |count|
      if (count % (FIZZ * BUZZ)) == 0
        print "FizzBuzz\n"
      elsif (count % FIZZ) == 0
        print "Fizz\n"
      elsif (count % BUZZ) == 0
        print "Buss\n"
      else
        print "#{count}\n"
      end
    end
    print "----------\n"
  end
end

fizzbuzz = FizzBuzz.new
fizzbuzz.answer 10
fizzbuzz.answer 30

ソースができたら、実行してみましょう。

$ mruby fizzbuzz.rb
take 1----------
1
2
Fizz
4
Buss
Fizz
7
8
Fizz
Buss
----------
take 2----------
1
2
Fizz
4
Buss
Fizz
7
8
Fizz
Buss
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buss
Fizz
22
23
Fizz
Buss
26
Fizz
28
29
FizzBuzz
----------

このように、ソースコード通りにFizzBuzzが実行されました。

mrdbを使ってみよう

f:id:ylgbk:20141223215551p:plain

mrdbを使用することで、プログラムを動かしながら動作を確認したり、問題箇所を特定することができます。mrdbはC言語のプログラムで使われるgdbと同等のインタフェースで操作することができます。

mrdbを起動する

まず、デバッガを起動します。

cygwinの端末上で以下のように入力します。

$ mrdb fizzbuzz.rb

ブレイクポイントを設定する

次に、プログラムを中断させたいポイントにブレイクポイントを設定します。

ブレイクポイントは「ファイル名と行番号」もしくは「クラス名とメソッド名」を指定して設定することができます。設定にはbreakコマンドを使います。

break (ファイル名):行番号

break (クラス名):メソッド

※()は省略可能、"break"は"b"に省略可能

例えば、こんな感じです。

(fizzbuzz.rb:1) b 27
Breakpoint 1: file fizzbuzz.rb, line 27.
(fizzbuzz.rb:1) b FizzBuzz:answer
Breakpoint 2: class FizzBuzz, method answer.

登録すると、ブレイクポイントに対して番号が割り振られます。

ブレイクポイントの一覧を確認する

ブレイクポイントが登録されたかどうか、一覧を表示して確認してみましょう。info breakpointsコマンドを入力します。

info breakpoints (ブレイクポイントNo)

※()を省略すると、全ブレイクポイントを表示。"info breakpoints"は"i b"に省略可能。

入力すると、一覧が表示されました。

(fizzbuzz.rb:1) i b
Num     Type           Enb What
1       breakpoint     y   at fizzbuzz.rb:27
2       breakpoint     y   in FizzBuzz:answer

プログラムを実行する

いよいよプログラムを起動します。runコマンドを入力します。

(fizzbuzz.rb:1) run
Breakpoint 1, at fizzbuzz.rb:27
27      fizzbuzz = FizzBuzz.new

ブレイクポイントを設定した27行目で停止しました。尚、この時点で再度runコマンドを入力すると、プログラムを最初からやり直します。

ブレイクポイント以降のプログラムを実行するためにはcontinueコマンドを入力します。("continue"は"c"に省略可能)

(fizzbuzz.rb:27) c
Breakpoint 2, FizzBuzz:answer
9         def answer(max)

ブレイクポイントを設定したFizzBuzzクラスのanswerメソッドで停止しました。

ソースコードを表示する

デバッグ中にソースコードを確認したいときは、listコマンドを入力します。

list (行番号)

※行番号を省略すると、実行中の行数から出力。"list"は"l"に省略可能

入力すると、ソースコードが部分的に表示されました。

(fizzbuzz.rb:9) l
9         def answer(max)
10          @take = @take + 1
11          print "take #{@take}----------\n"
12          (1..max).each do |count|
13            if (count % (FIZZ * BUZZ)) == 0
14              print "FizzBuzz\n"
15            elsif (count % FIZZ) == 0
16              print "Fizz\n"
17            elsif (count % BUZZ) == 0
18              print "Buss\n"

1行だけ実行する

stepコマンドを入力すると、1行だけ進みます。

(fizzbuzz.rb:9) step
fizzbuzz.rb:10
10          @take = @take + 1
(fizzbuzz.rb:10) step
fizzbuzz.rb:11
11          print "take #{@take}----------\n"

変数の値を書き換える

evalコマンドを使うことで、変数の値を書き換えたり、表示したりすることができます。

eval (実行したい式)

このように使用します。

(fizzbuzz.rb:11) eval @take = 3
$1 = 3

その他のコマンド

その他、使えるコマンドは(mruby debugger 操作マニュアル)http://forum.mruby.org/docs/dmanual.htmlを参考にしてください。

まとめ

このように、mrubyの開発環境は簡単に構築できます。デバッガが登場したことで、プログラムのバグを見つけるのも容易になりました。

mrubyを使うことでETロボコンの戦略が多様化したり、ソースが読みやすくなることで大人数での開発が簡単になったりと、様々なメリットが期待されます。来年度、使ってみたいと思っている人は、ぜひオフシーズン中にmrubyを触ってみてください。その心地良さが体感できるはずです。

ついにクリスマスイブです。明日はいよいよ最終日となりますので、お楽しみに!