1 00:00:00,560 --> 00:00:01,360 みなさん、こんにちは。 2 00:00:01,520 --> 00:00:04,800 今回はデバッガを簡単に紹介して ブレークポイントの概念と 3 00:00:04,960 --> 00:00:09,360 Pharo での色々なブレークポイントを 説明します。 4 00:00:09,600 --> 00:00:11,560 システムは生きていて 5 00:00:11,760 --> 00:00:14,760 システムや 6 00:00:14,920 --> 00:00:18,040 システム中のオブジェクトと 対話することを学びます。 7 00:00:18,840 --> 00:00:22,000 ソースコードを扱うのではなく オブジェクトを扱います。 8 00:00:22,160 --> 00:00:25,520 オブジェクトには状態があり メッセージを送ったり受けたりします。 9 00:00:26,760 --> 00:00:29,200 デバッガを使うことを 怖がらないでください。 10 00:00:29,360 --> 00:00:33,480 デバッガでコードを書いたり 動いているプログラムをインスペクトしたり 11 00:00:33,920 --> 00:00:37,360 強力で本当に「使える」ツールです。 12 00:00:37,920 --> 00:00:41,040 デバッガ上で直接開発する開発者を 13 00:00:41,200 --> 00:00:45,360 自分も含め何人も知っています。 14 00:00:45,520 --> 00:00:49,440 コードブラウザ以外にも 膨大な量のコードが 15 00:00:49,600 --> 00:00:51,280 デバッガ上で書かれています。 16 00:00:51,440 --> 00:00:54,040 その利点は コードを書いている時に 17 00:00:54,200 --> 00:00:58,400 メソッドのコンテキストや オブジェクトや変数にアクセスできる点です。 18 00:00:58,560 --> 00:01:00,960 そういったことを見たり 試行したりすることができます。 19 00:01:01,120 --> 00:01:04,640 コードを書いている時に 全てのデータを渡して 20 00:01:04,800 --> 00:01:06,360 テストすることができるのです。 21 00:01:06,920 --> 00:01:10,280 デバッガはこんな表示になっています。 22 00:01:10,440 --> 00:01:14,560 タイトルバーがあって エラーメッセージを表示しています。 23 00:01:14,720 --> 00:01:16,920 スタックがあります。コールスタックです。 24 00:01:17,080 --> 00:01:20,200 メソッドを呼ぶスタックです。 ここを見ると 25 00:01:20,360 --> 00:01:24,440 この performTest メソッドは testSumming メソッドを呼んでいて 26 00:01:24,600 --> 00:01:27,600 それが + メソッドを呼んでいます。 27 00:01:27,760 --> 00:01:32,400 その + メソッドが doesNotUnderstand:を発生させています。 28 00:01:33,680 --> 00:01:37,720 ここで選ばれたメソッドの コードがここに表示されます。 29 00:01:37,880 --> 00:01:41,440 ここで DiceHandle クラスの + メソッドが選択されています。 30 00:01:41,600 --> 00:01:44,480 それでそのコードが下側に表示されています。 31 00:01:44,640 --> 00:01:48,640 一番下の部分には 色々な変数があります。 32 00:01:48,800 --> 00:01:50,760 この実行中のコンテキストで 33 00:01:50,920 --> 00:01:53,720 アクセス可能な変数全てです。 34 00:01:53,880 --> 00:01:56,480 変数を変更したり 35 00:01:56,640 --> 00:01:59,840 そのオブジェクトをインスペクトしたり できます。 36 00:02:00,400 --> 00:02:04,000 ここに一連のアクションがあります。 37 00:02:04,160 --> 00:02:08,280 メソッドの再実行をしたり 呼び出し先に潜り込んだり 38 00:02:08,440 --> 00:02:10,760 何が起こっているのか1行ずつ見たり することができます。 39 00:02:11,400 --> 00:02:14,880 デバッガが開いた時 それを閉じても何も解決しません。 40 00:02:15,160 --> 00:02:17,560 デバッガを開いて 41 00:02:17,720 --> 00:02:21,200 何が問題を起こしているのか 詳しく中を見る方がずっと簡単です。 42 00:02:21,360 --> 00:02:24,120 デバッガでコールスタックや 43 00:02:24,280 --> 00:02:26,240 オブジェクトを精査して 問題を修正するほうが 44 00:02:26,400 --> 00:02:30,040 デバッガを閉じてから原因を 推測するよりずっと簡単です。 45 00:02:31,480 --> 00:02:34,840 デバッガはともだちです。 46 00:02:35,000 --> 00:02:37,560 デバッガを使ってコンテキスト中の オブジェクトや 47 00:02:37,720 --> 00:02:42,440 インスタンス変数などと対話します。 48 00:02:42,600 --> 00:02:47,040 変数の状態をチェックしたり あるいは修正してしまったりします。 49 00:02:48,000 --> 00:02:51,560 オブジェクトの状態をチェックするために メッセージを送ったり 50 00:02:51,720 --> 00:02:54,440 どう反応するのかをチェックします。 51 00:02:55,080 --> 00:02:59,160 もちろんコールスタック上のメソッドを 修正してセーブして 52 00:02:59,320 --> 00:03:02,160 新しいコードで実行を継続できます。 53 00:03:02,320 --> 00:03:06,920 最初から再実行することなく。 54 00:03:07,400 --> 00:03:10,120 メソッドが失敗した時に そのメソッドを修正して 55 00:03:10,280 --> 00:03:14,080 そのメソッドを再実行して プログラムは実行継続します。 56 00:03:15,000 --> 00:03:16,200 とてもよく使われる 57 00:03:17,040 --> 00:03:19,240 デバッグ手法に 58 00:03:19,680 --> 00:03:22,400 コンソールに表示する というものがあります。 59 00:03:22,560 --> 00:03:27,200 それは実際には 60 00:03:27,360 --> 00:03:31,720 デバッグ手法としてはとても残念なもので 61 00:03:32,320 --> 00:03:37,480 トレースしたい全てのメソッドを修正して 問題が修正されたら再び 62 00:03:37,640 --> 00:03:40,600 全てのトレースを取り除かなければなりません。 63 00:03:40,760 --> 00:03:44,400 その上、問題がどこにありそうか 64 00:03:44,560 --> 00:03:47,680 どこから問題が入り込んでくるのか およその見当がついていなければ 65 00:03:47,840 --> 00:03:52,440 トレースとしてどこで何を表示するか 決められません。 66 00:03:52,760 --> 00:03:57,240 もう1つの方法にブレークポイントがあります。 67 00:03:57,680 --> 00:04:01,920 ブレークポントは次に通過する時に 68 00:04:02,080 --> 00:04:06,040 実行を停止するように Pharo に 指示するコードです。 69 00:04:06,200 --> 00:04:09,560 最も簡単なブレークポントは Halt now です。 70 00:04:09,720 --> 00:04:13,800 Halt クラスに now メッセージを 送ります。 71 00:04:13,960 --> 00:04:17,360 すると直ちに実行を停止します。 72 00:04:17,520 --> 00:04:19,520 ここからデバッガが開きます。 73 00:04:19,680 --> 00:04:23,760 何が起こるのか1行ずつプログラムの状態を 見ていくことができます。 74 00:04:24,320 --> 00:04:27,520 つまり Halt now はプログラムを 一時停止させます。 75 00:04:27,680 --> 00:04:30,120 再実行することもできますが 当面は一時停止しています。 76 00:04:30,280 --> 00:04:33,880 そしてアプリケーションの現状態で デバッガを開きます。 77 00:04:34,040 --> 00:04:36,120 Halt now はとても良いのですが 78 00:04:36,280 --> 00:04:40,120 システムにより実行されるものも含めて 79 00:04:40,320 --> 00:04:43,200 定常的に実行されるメソッドに置いてしまうと 80 00:04:43,360 --> 00:04:48,120 デバッガが何十個も開いてしまう ことになります。 81 00:04:48,280 --> 00:04:52,520 Halt now をデバッガを開く時に 82 00:04:52,920 --> 00:04:55,800 使われるコードに置いてしまうと 83 00:04:55,960 --> 00:04:57,400 デバッガを開こうとした時に 84 00:04:57,560 --> 00:04:59,440 それ自身が Halt now を実行してしまい また別のデバッガを開くことになり 85 00:04:59,600 --> 00:05:04,200 ということが繰り返され システムを止めてしまいます。 86 00:05:04,520 --> 00:05:07,760 この場合、 Halt once を使います。 87 00:05:07,920 --> 00:05:12,520 Halt once は一度実行されたら 実行を停止しますが 88 00:05:12,680 --> 00:05:17,240 それ以降は何度実行されても 実行を停止しません。 89 00:05:18,520 --> 00:05:22,120 Halt once はコードのどこにでも 置くことができます。 90 00:05:23,880 --> 00:05:26,200 一度だけ実行されて 91 00:05:26,360 --> 00:05:28,280 デバッガーを開いて 92 00:05:28,440 --> 00:05:31,680 すぐに無効になります。 93 00:05:32,360 --> 00:05:35,240 もう1つの方法は一定の回数の実行後に 停止することです。 94 00:05:35,640 --> 00:05:38,560 例えば 10 回繰り返された後で停止すれば 95 00:05:38,720 --> 00:05:42,080 あるコレクションの10個目の要素に 何かある場合に 96 00:05:42,240 --> 00:05:44,800 それまでの 9 回は 97 00:05:44,960 --> 00:05:47,880 デバッガを開いても無駄なわけです。 98 00:05:48,040 --> 00:05:51,000 なので 10 回目に停止したいわけです。 99 00:05:52,040 --> 00:05:56,280 あるいは特定の条件を満たす時だけ 100 00:05:56,520 --> 00:05:59,920 停止することも考えられます。 101 00:06:00,080 --> 00:06:02,040 Halt if: は 102 00:06:02,240 --> 00:06:04,200 メソッド名のシンボルが引数の場合には 103 00:06:04,400 --> 00:06:07,480 コールスタック上にそのメソッドが ある場合にデバッガを開きます。 104 00:06:07,640 --> 00:06:11,280 つまり、Dice>>faces のコードに Halt if: #printString を入れると 105 00:06:11,440 --> 00:06:15,920 Dice>>faces が 106 00:06:16,080 --> 00:06:18,000 printString メソッドから 呼ばれている時だけ 107 00:06:18,160 --> 00:06:20,200 ブレークポイントが 108 00:06:20,520 --> 00:06:23,120 働いて、プログラムを一時停止させます。 109 00:06:23,720 --> 00:06:25,360 if: は引数としてブロックを取ることもできます。 110 00:06:25,520 --> 00:06:28,320 ブロック内のコードが 111 00:06:28,480 --> 00:06:32,680 true の場合だけプログラムを一時停止して 112 00:06:32,880 --> 00:06:35,080 デバッガを開きます。 113 00:06:35,320 --> 00:06:38,840 Pharo ではテストもコールスタック中の メソッドなので 114 00:06:39,000 --> 00:06:42,840 テストから実行された時だけ 115 00:06:43,000 --> 00:06:45,400 一時停止することができます。 116 00:06:45,960 --> 00:06:49,560 now、once、onCount:、if: といったメソッドはどれも 117 00:06:50,240 --> 00:06:53,000 Halt クラスのメソッドです。 118 00:06:53,160 --> 00:06:56,720 コードを勉強して どうやって実装されているか見ることができます。 119 00:06:56,880 --> 00:06:59,880 そして自分のメソッドを追加して 120 00:07:00,040 --> 00:07:03,760 自分にとって必要な独自の ブレークポイントを作ることもできます。 121 00:07:03,920 --> 00:07:06,240 下の例では 122 00:07:06,400 --> 00:07:11,080 between:and: というブレークポイントを 実装しました。 123 00:07:11,240 --> 00:07:14,280 minTime から maxTime までの間だけ 124 00:07:14,440 --> 00:07:19,320 プログラムを停止させるものです。 125 00:07:20,400 --> 00:07:23,800 つまり正子から午前2時までの間だけ 126 00:07:23,960 --> 00:07:27,640 プログラムを停止させて デバッガを開きます。 127 00:07:27,800 --> 00:07:31,240 デバッガはとても強力なツールです。 128 00:07:31,560 --> 00:07:35,280 システムで沢山のブレークポイントを 定義していますが 129 00:07:35,440 --> 00:07:37,760 必要なだけ追加することができます。 130 00:07:37,920 --> 00:07:41,360 ブレークポイントを使うと メソッドを変更してデバッガを開いて 131 00:07:41,520 --> 00:07:44,240 何が起きているのか1行ごとに 見ていくことができます。 132 00:07:45,120 --> 00:07:48,720 ブレークポイントは本当に強力です。 133 00:07:48,880 --> 00:07:52,440 ブレークポイントやデバッガを使う ことを躊躇しないでください。