2010-03-02
Perlデバッガの手引き
Perlのとても便利な道具のひとつにデバッガがあります。デバッガを使うとスクリプトを一行づつたどって変数の中身を見たり、ブレークポイントを設定してその位置で停止したりすることができます。
デバッガは本当に便利なのですがPerlをやっていても意外と知らない人がいます。ひとたびデバッガを覚えてしまうと試験をするときに手放せなくります。Perlを覚えたての時期からどんどん使っていって欲しいツールです。そんなデバッガのコマンドとテクニックをまとめてみました。
デバッグ用のスクリプト
デバッグ用の簡単なスクリプトを準備しました。debug.plという名前で保存してください。このスクリプトを使用してデバッガの解説をします。
my $message = 'Hello'; my @nums = (1, 2, 3); my %scores = (math => 80, english => 77); my $twice = twice(5); # ブレークポイント $DB::single = 1; for my $num (@nums) { # 条件付ブレークポイント if ($num == 2) { $DB::single = 1 } print "$num\n"; } sub twice { my $num = shift; return $num * 2; }
デバッガの起動
デバッガを起動するには「-d」オプションを指定してperlを起動します。
perl -d debug.pl
デバッガを起動すると最初の行で停止します。
main::(a.pl:4): my $message = 'Hello';
デバッガを終了するには「q」を使用します。
q
ヘルプを見るには「h」を使用します。
h
では順番にデバッガのコマンドを覚えていきましょう。
1. 実行系のコマンド
Perlデバッガの実行系のコマンドを解説します。
n - 一行実行
スクリプトを一行実行するには「n」を使用します。「n」と入力して「Enter」を入力すると次の行に進みます。
最初の状態で「n」を実行すると次のように表示され一行進んでいることが確認できます。
main::(a.pl:5): my @nums = (1, 2, 3);
「n」「Enter」「n」「Enter」と入力していくとスクリプトの最後にたどり着いてスクリプトが終了します。
Debugged program terminated. Use q to quit or R to restart,
デバッグをやめるかリスタートするかを聞かれますが2回目のデバッグを行いたいときは必ずqでデバッグをいったん終えてください。
「n」「Enter」「n」「Enter」と入力するのは少し面倒です。実は「n」「Enter」「Enter」「Enter」で行を進めていくことができます。「n」か「s」が直前に入力されていた場合は「Enter」で直前のコマンドを繰り返すことができます。
nは「next」のnだと覚えると覚えやすいです。
s - シングルステップ実行
スクリプトをシングルステップ実行するには「s」を使用します。「n」との違いはサブルーチンの内部の処理もたどってくれることです。
「n」で一行実行を勧めてスクリプトをサブルーチンの呼び出しがある行まで進めてください。
main::(a.pl:8): my $twice = twice(5);
この行で「s」を実行するとサブルーチンの内側の処理に移動することができます。
main::twice(a.pl:21): my $num = shift;
c - ブレークポイントあるいは指定した行まで実行
「c」はブレークポイントあるいは指定した行まで実行するコマンドです。cはcontinueの頭文字のcです。
c 5
を実行すると5行目の直前までが実行されます。
main::(a.pl:5): my @nums = (1, 2, 3);
次に引数を与えずに
c
を実行すると文中のブレークポイントの次の位置まで進みます。
main::(a.pl:13): for my $num (@nums) {
# ブレークポイント $DB::single = 1;
はスクリプトの中に埋め込むことができるブレークポイントです。変数の内容などを見たい場合にその直前の行あたりにブレークポイントを設定しておくと、そこで実行を停止することができるのでとても便利です。
2. 表示系のコマンド
表示系のコマンドを解説します。
p - 変数の内容を表示
「p」で変数の内容を表示することができます。たとえば$messageという変数を表示したい場合は以下のようにします。
p $message
x - 変数の内容を展開して表示
「p」はスカラ変数の内容を表示するには便利ですがハッシュや配列、またもっと複雑なデータ構造を表示するには適していません。
「x」を使用するとデータの内部構造をわかりやすく表示することができます。「x」の引数にはリファレンスを渡す必要がありますので注意してください。
たとえば%scoresの内容を表示するには次のようにします。\はリファレンスを取得するためのものです。
x \%scores
次のように変数のデータがわかりやすく表示されます。
0 HASH(0x19b205c) 'english' => 77 'math' => 80
3. その他のよく使用するコマンド
その他のよく使用するコマンドを解説します。
v - 周辺の行の表示
「v」で周辺の行を表示することができます。
v
4行目で「v」を実行すると次のように周辺の行が表示されます。
1: use strict; 2: use warnings; 3 4==> my $message = 'Hello'; 5: my @nums = (1, 2, 3); 6: my %scores = (math => 80, english => 77);
「v」を何回も実行すると下の行に表示を移していくことができます。
. - 現在行の表示
「v」を何回も実行すると下の行に表示が移動してしまいます。そういうときに現在行に戻るために「.」を使用することができます。
.
任意のperlの文
デバッガでは任意のPerlの文を実行することができます。以下は変数が定義されているかどうかを確認してみるためにdefined関数を使った例です。
print defined $message;
どのような文でも実行することができるので確認に役立ちます。
4. デバッグのテクニック
よく使用するデバッグのテクニックを紹介します。
文中ブレークポイント
Perlではスクリプトの中にブレークポイントを埋め込むことができます。DBクラス(デバッガのためのクラス)のsingleという変数に1を代入しておくとその位置でシングルステップ実行に処理が切り替わる仕組みです。
$DB::single = 1;
これは本当に便利なのでどんどん使ってください。また試験を終えた後はスクリプトの中から削除するのを忘れないようにしましょう。
条件つきブレークポイント
デバッグを行っているとある条件のときだけ処理をそこで止めて変数の内容を見たいというときがあります。そのような場合は、条件文と「$DB::single = 1」を組み合わせて使います。今回のサンプルでは$numが2のときにその位置でデバッガが停止するようにしています。
if ($num == 2) { $DB::single = 1 }
警告が発生した位置を調べる
スクリプトの試験をしていると以下のような未定義値を使用していますという意味の警告がよく発生します。
Use of uninitialized value
特に原因を発見するのが大変なのはforやwhileなどのループの中で警告が発生した場合です。これはどこかで代入すべきだったのに代入できていないとうことなので、その場所を特定する必要があります。
ほとんどの人はこのような場合はなんとなくこの場所だろうという位置までデバッガを進めると思うのですが、実は警告をキャッチする方法があります。
Perlでは警告をシグナルとして受け取ることができるので、ループのブロックの中に次のようなブレークポイントを仕掛けてあげればよいです。
# 警告をキャッチしてブレークポイントしかける $SIG{__WARN__} = sub { $DB::single = 1; };
デバッガを積極的に活用してみてください
これでデバッガのコマンドとテクニックの解説を終わります。デバッガのコマンドはたくさんありますが、ここに書いておいてものだけ覚えておけばデバッグで困ることはないでしょう。デバッガは本当に有用なツールなので積極的に活用してみてください。
- 7721 https://www.google.co.jp/
- 4130 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&sqi=2&ved=0CC0QFjAA&url=http://d.hatena.ne.jp/perlcodesample/20100302/1269670120&ei=tZchUceuMoa0kAX6-oHgAQ&usg=AFQjCNH-J98HDtJ8tMTQHYOVjt6idhw_hg&bvm=bv.42553238,d.dGY
- 2146 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=1&ved=0CC8QFjAA&url=http://d.hatena.ne.jp/perlcodesample/20100302/1269670120&ei=aIwhUYHGJKz3mAX4l4CQCg&usg=AFQjCNH-J98HDtJ8tMTQHYOVjt6idhw_hg&sig2=wnd_r1I9sV0BLbh-_fKB9w&bvm=
- 962 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&sqi=2&ved=0CDkQFjAC&url=http://d.hatena.ne.jp/perlcodesample/20100302/1269670120&ei=yLwmUY7pMoj3mAW-3oDQAw&usg=AFQjCNH-J98HDtJ8tMTQHYOVjt6idhw_hg&bvm=bv.42768644,d.dGY
- 943 http://www.google.co.jp/url?url=http://d.hatena.ne.jp/perlcodesample/20100302/1269670120&rct=j&frm=1&q=&esrc=s&sa=U&ei=FX9PU9GsHs6UkgXvsIGQCw&ved=0CB4QFjAA&usg=AFQjCNEzNSG7HFUyEClGKQBBs-W7eryQ6g
- 572 https://www.google.co.jp
- 547 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&ved=0CDgQFjAB&url=http://d.hatena.ne.jp/perlcodesample/20100302/1269670120&ei=O84iUbqOMMuWkQXflICYCQ&usg=AFQjCNH-J98HDtJ8tMTQHYOVjt6idhw_hg
- 498 http://search.yahoo.co.jp/search?p=perl+デバッガ+コマンド&ei=UTF-8&fr=top_ga1_sa&x=wrt
- 492 http://www.google.co.jp/url?sa=t&rct=j&q=perl+????????????&source=web&cd=1&ved=0CDAQFjAA&url=http://d.hatena.ne.jp/perlcodesample/20100302/1269670120&ei=tNYhUcWXEJGbmQXYsoGwCg&usg=AFQjCNH-J98HDtJ8tMTQHYOVjt6idhw_hg
- 446 http://www.google.co.jp/url?sa=t&rct=j&q=perl デバッグ ブレークポイント&source=web&cd=1&cad=rja&ved=0CC0QFjAA&url=http://d.hatena.ne.jp/perlcodesample/201003