1 00:00:01,540 --> 00:00:03,650 このビデオでは インスペクターを使って 2 00:00:03,817 --> 00:00:08,710 システムの内部を掘り進めていきながら 理解していくための 3 00:00:08,877 --> 00:00:09,620 方法をお見せします。 4 00:00:10,880 --> 00:00:15,020 インスペクターは いわば顕微鏡のようなもので 5 00:00:15,187 --> 00:00:17,910 システムの内部に行って 探検することができます。 6 00:00:18,077 --> 00:00:21,190 また、システムを修正していくための 7 00:00:21,357 --> 00:00:22,860 プローブのようでもあります。 8 00:00:23,027 --> 00:00:26,940 バクテリアを操って反応させる 生物学者になったかのようです。 9 00:00:27,800 --> 00:00:32,240 Smalltalk globals の探検を 楽しんでいきましょう。 10 00:00:34,910 --> 00:00:37,470 これは実際には名前空間です。 Pharo の全てのクラスが 11 00:00:37,637 --> 00:00:40,050 格納された場所です。 12 00:00:41,770 --> 00:00:44,000 つまり辞書です。 SystemDictionary は辞書です。 13 00:00:44,167 --> 00:00:48,180 興味深いことに 14 00:00:48,630 --> 00:00:53,540 インスペクターを使って見ると 15 00:00:53,707 --> 00:00:56,240 値が埋め込まれた 16 00:01:00,080 --> 00:01:00,860 大きなテーブルに見えます。 17 00:01:01,027 --> 00:01:02,410 例えば、そうですね… 18 00:01:02,577 --> 00:01:06,770 Breakpoint を見てみると 19 00:01:07,680 --> 00:01:11,840 ここにオブジェクトがあって 20 00:01:12,710 --> 00:01:14,350 キーと値があります。 21 00:01:14,517 --> 00:01:16,190 インスペクターで 22 00:01:16,357 --> 00:01:20,390 例えばこの テーブルの 23 00:01:20,557 --> 00:01:22,370 2 の要素をみると 24 00:01:22,537 --> 00:01:24,150 グローバル変数と呼ばれるものを 捕まえることができます。 25 00:01:24,317 --> 00:01:26,150 グローバル変数というのは 26 00:01:26,317 --> 00:01:28,350 キーと値からなるオブジェクトで 27 00:01:29,220 --> 00:01:33,040 キーはというと、クリックしてみると 28 00:01:33,207 --> 00:01:37,870 ByteSymbol になっています。 これが名前です。 29 00:01:38,037 --> 00:01:42,720 一旦戻って、値を見てみると 30 00:01:42,887 --> 00:01:44,820 クラスが得られます。 31 00:01:45,000 --> 00:01:47,520 ではクラスの内部に進んでいきましょう。 32 00:01:48,000 --> 00:01:49,230 ここでスタート地点に戻ります。 33 00:01:50,460 --> 00:01:54,790 Pharo の新しいインスペクターは 34 00:01:55,670 --> 00:01:59,440 開発したチームに因んで GT Inspector と呼ばれていますが 35 00:01:59,607 --> 00:02:03,380 対象ごとに専用のタブを 36 00:02:03,547 --> 00:02:05,220 提供してくれます。 37 00:02:06,610 --> 00:02:08,570 SystemDictionary に対しては どんな専用タブがあるかというと 38 00:02:08,737 --> 00:02:12,210 キーと値のペアを 39 00:02:12,377 --> 00:02:17,240 表示するタブや 40 00:02:17,407 --> 00:02:18,220 キーのみを表示するタブがあります。 41 00:02:18,387 --> 00:02:20,340 キーのみのほうは 42 00:02:20,507 --> 00:02:25,270 クラス名を表示するだけになるので 43 00:02:25,437 --> 00:02:26,070 今回はあまり面白くないです。 44 00:02:26,237 --> 00:02:28,720 このインスペクターの 45 00:02:28,887 --> 00:02:33,170 ブラウズの仕方を 46 00:02:33,337 --> 00:02:34,730 例で説明しましょう。 47 00:02:35,270 --> 00:02:39,410 オブジェクトから別のオブジェクトに 48 00:02:39,620 --> 00:02:42,390 対象の構造からパスを選択して ブラウズしています。 49 00:02:42,940 --> 00:02:44,900 キーのことを知りたい場合には、こう。 50 00:02:45,067 --> 00:02:47,600 値について知りたい時は、こうして クラスを掴んで 51 00:02:47,767 --> 00:02:49,420 さらにこのクラスのメソッド辞書に 進んでいくことができます。 52 00:02:49,790 --> 00:02:53,730 メソッド辞書から 53 00:02:53,897 --> 00:02:54,840 コンパイル済みメソッド(CompiledMethod) 等に進んでいくことができます。 54 00:02:55,007 --> 00:02:58,960 このツールでブラウズしていく過程のうち 55 00:02:59,127 --> 00:03:03,810 表示する部分を変えて フロー全体を見ることもできます。 56 00:03:04,510 --> 00:03:08,540 さらに良いことに 57 00:03:08,940 --> 00:03:11,530 フローの中で分岐を作ることもできます。 58 00:03:12,130 --> 00:03:14,570 ここでやってみましょう。 59 00:03:14,737 --> 00:03:16,300 スタート地点に戻ります。 60 00:03:18,070 --> 00:03:22,560 さて、ではここで 61 00:03:22,727 --> 00:03:24,530 Point クラスに興味があるとします。 62 00:03:24,920 --> 00:03:26,600 通常、Point クラスに アクセスするためには 63 00:03:26,767 --> 00:03:29,050 Smalltalk globals at: #Point とすれば良いことは分かっています。 64 00:03:29,217 --> 00:03:31,890 さてここで、それを実行して 65 00:03:32,057 --> 00:03:36,670 インスペクターで開くように 66 00:03:36,837 --> 00:03:39,280 インスペクターの内部でやってみましょう。 67 00:03:41,340 --> 00:03:45,270 すると突然 68 00:03:45,437 --> 00:03:50,230 元のナビゲーションから 69 00:03:50,580 --> 00:03:52,230 これから進んでいくナビゲーションが 分岐します。 70 00:03:54,440 --> 00:03:56,380 こうすることで 71 00:03:56,547 --> 00:03:59,330 いくつも表現式を入力して ナビゲーションを開始することができます。 72 00:04:00,760 --> 00:04:01,750 ここでは 73 00:04:02,120 --> 00:04:04,520 Point クラスを見ています。 74 00:04:04,760 --> 00:04:09,000 インスペクターは 75 00:04:09,167 --> 00:04:12,400 クラスを見る専用のタブを 表示しています。 76 00:04:12,860 --> 00:04:17,490 ここでは、Raw タブは 77 00:04:17,657 --> 00:04:20,030 Point クラスは 78 00:04:20,197 --> 00:04:23,760 Kernel カテゴリーで定義されていて environment は同じ空間を指していて 79 00:04:24,010 --> 00:04:28,960 インスタンスのフォーマットや 80 00:04:29,127 --> 00:04:30,470 layout があります。 81 00:04:30,637 --> 00:04:35,520 端的に言えば、これがクラスというものの Pharo での実装です。 82 00:04:36,220 --> 00:04:38,920 このインスペクターを使って 83 00:04:39,087 --> 00:04:41,810 例えば定義や 84 00:04:42,000 --> 00:04:46,790 コメントを見ることができます。 参照(All Ref)などの他のタブもあります。 85 00:04:46,957 --> 00:04:49,550 All Ref をクリックすると 86 00:04:49,717 --> 00:04:54,610 Point は @ メソッドで 87 00:04:54,777 --> 00:04:56,000 使われていることがわかります。 88 00:04:57,200 --> 00:04:59,540 さらに見てみると 89 00:04:59,920 --> 00:05:02,500 これがメソッドを表現するオブジェクトの 90 00:05:02,667 --> 00:05:05,630 生(Raw)の情報です。 ここにソース(Source)があります。 91 00:05:05,797 --> 00:05:07,790 使う状況にあわせて 92 00:05:07,957 --> 00:05:09,770 タスクに最適な表現を 選ぶことができます。 93 00:05:10,440 --> 00:05:11,700 では戻ってみましょう。 94 00:05:13,440 --> 00:05:16,810 クラスを見て 95 00:05:18,740 --> 00:05:21,950 メソッド辞書に行きたくなったとします。 96 00:05:22,117 --> 00:05:25,660 メソッド辞書というのは 97 00:05:25,827 --> 00:05:27,930 メソッドの名前がキーで 98 00:05:28,097 --> 00:05:31,870 コンパイル済みメソッドが値となっている 辞書です。 99 00:05:32,037 --> 00:05:35,490 コンパイル済みメソッドのインスタンスを 100 00:05:35,657 --> 00:05:37,730 生(Raw)で見てみると ちょっと厄介な感じです。 101 00:05:38,680 --> 00:05:43,540 対話するためには 102 00:05:43,707 --> 00:05:45,820 メソッド辞書が どう実装されているのかを 103 00:05:46,000 --> 00:05:47,940 理解していなければなりません。 しかし実装には興味ありません。 104 00:05:48,107 --> 00:05:49,420 コンパイル済みメソッドを 見たいだけなのです。 105 00:05:49,930 --> 00:05:51,460 コンパイル済みメソッドを見るためには 106 00:05:51,627 --> 00:05:54,670 例えば degrees を選びます。 107 00:05:54,837 --> 00:05:57,570 これでコンパイル済みメソッドを 掴むことができます。 108 00:05:58,270 --> 00:06:01,280 コンパイル済みメソッドは 109 00:06:01,447 --> 00:06:05,610 これまた専用のインスペクター上の 表示を提供しています。 110 00:06:06,810 --> 00:06:10,300 コンパイル済みメソッドを見ると 111 00:06:10,467 --> 00:06:13,700 これは実際にはデータのフレームワークで 112 00:06:13,867 --> 00:06:17,570 テーブルになっています。 113 00:06:17,737 --> 00:06:19,810 具体的にはバイトコードとリテラルを 持っています。 114 00:06:20,100 --> 00:06:21,790 リテラルというのは 115 00:06:21,957 --> 00:06:25,620 コード中に asFloat や arcTan や degrees や radianToDegrees がありますが 116 00:06:27,900 --> 00:06:30,100 これらのメッセージ名がどこかに 格納されていなければなりませんが 117 00:06:31,000 --> 00:06:33,820 それがリテラルとしてここに格納されています 118 00:06:37,780 --> 00:06:38,413 コンパイル済みメソッドの 最初のほうに見えます。 119 00:06:38,580 --> 00:06:39,213 バイトコードは何をするのかというと 120 00:06:39,380 --> 00:06:41,880 スタックにオブジェクトを入れて 121 00:06:42,047 --> 00:06:43,830 メソッドを起動したりします。 122 00:06:44,000 --> 00:06:45,860 ここでは例えば 123 00:06:46,027 --> 00:06:49,810 ビューを最小化しますが Bytecode ビューを見ると 124 00:06:50,000 --> 00:06:51,400 そこでは 125 00:06:51,567 --> 00:06:55,470 PushRcvr してからスタックに 0 を入れて それから = をしています。 126 00:06:55,637 --> 00:06:56,900 これと対応しているのは何でしょう? 127 00:06:57,240 --> 00:06:58,870 よく見てみます。 128 00:07:03,330 --> 00:07:06,700 表示モードは本当にとても便利です。 129 00:07:06,867 --> 00:07:08,690 何ができるのかというと 130 00:07:08,857 --> 00:07:11,910 こうしてソースコードを見る時 131 00:07:12,077 --> 00:07:16,880 あちらで Bytecode を選んで 132 00:07:17,047 --> 00:07:20,350 こちらで Source を選ぶと 対応するもの同士が 133 00:07:20,517 --> 00:07:21,900 表示されます。 134 00:07:22,690 --> 00:07:23,480 すごいですね。 135 00:07:23,890 --> 00:07:27,260 つまりレシーバーの インスタンス変数 0 番をプッシュして 136 00:07:27,427 --> 00:07:30,920 0 をスタックに置いて 137 00:07:31,087 --> 00:07:33,700 そして = メッセージを送ります。 138 00:07:34,560 --> 00:07:36,390 つまりコンパイラを開発する人は 139 00:07:36,557 --> 00:07:38,670 生成されたバイトコードを 140 00:07:38,837 --> 00:07:42,230 コードの構造に対応付けて 141 00:07:42,397 --> 00:07:45,740 見ることができるのです。 142 00:07:45,940 --> 00:07:50,220 同様に 143 00:07:50,387 --> 00:07:54,780 戻って 144 00:07:58,320 --> 00:08:00,590 self をクリックすると 145 00:08:04,900 --> 00:08:07,700 ここにコンパイル済みメソッドの 表示が 2 つあります。 146 00:08:10,930 --> 00:08:13,000 ここにコンパイル済みメソッドの 表示が 2 つあって、これで 147 00:08:13,167 --> 00:08:16,920 AST(抽象構文木)を見ます。 148 00:08:18,680 --> 00:08:20,510 これとソースを見ます。 149 00:08:20,677 --> 00:08:23,490 これで内部をブラウズすることもできます。 150 00:08:23,657 --> 00:08:26,630 例えば、抽象構文木は 151 00:08:26,797 --> 00:08:31,420 このメソッドのものは複雑ですが 表示を開いていって 152 00:08:31,587 --> 00:08:35,270 一時変数 tan を選択すると 153 00:08:36,780 --> 00:08:41,610 それと対応する 154 00:08:42,410 --> 00:08:44,030 コード片が選択されます。 155 00:08:44,197 --> 00:08:46,510 これもすごいですね。 さらに 156 00:08:46,677 --> 00:08:50,760 x に 0 を引数として送るメッセージは 157 00:08:50,927 --> 00:08:54,000 この抽象構文木のこの部分ですが 158 00:08:54,440 --> 00:08:55,820 この部分に対応しています。 159 00:08:57,530 --> 00:09:01,860 インスペクターを使って 160 00:09:02,027 --> 00:09:04,670 木のノードを選択することで 161 00:09:04,837 --> 00:09:06,880 テキストの選択部分を 管理することができます。 162 00:09:08,000 --> 00:09:12,120 Pharo のコンパイラを開発する 人たちにとって 163 00:09:12,287 --> 00:09:13,400 とても素晴らしいツールになります。 164 00:09:14,080 --> 00:09:16,220 このアプローチを使って 165 00:09:16,387 --> 00:09:20,460 様々なドメイン、つまりあなたの ドメインオブジェクトに対しても 166 00:09:20,627 --> 00:09:24,060 意味が解りやすいような表示を 提案するように 167 00:09:24,420 --> 00:09:27,680 インスペクターを拡張することが できるのです。