1 00:00:00,520 --> 00:00:05,760 こんにちは。継承とメソッド探索の 第 4 講へようこそ。 2 00:00:06,360 --> 00:00:11,360 アルゴリズムがメソッドを見つけられなかった 場合に何が起こるのかを学びます。 3 00:00:11,800 --> 00:00:13,120 この講義で 4 00:00:14,360 --> 00:00:18,440 メソッドが見つからず 5 00:00:18,920 --> 00:00:23,000 メッセージを理解できなかった という事実を扱う処理を 6 00:00:23,160 --> 00:00:24,920 クラスのコードで追加する方法が わかるようになります。 7 00:00:25,600 --> 00:00:28,680 メッセージ送信を簡単に復習しましょう。 8 00:00:29,520 --> 00:00:33,400 area メッセージが ColoredRectangle に 送られます。 9 00:00:33,760 --> 00:00:38,800 まず、アルゴリズムは メッセージにマッチするメソッドを探します。 10 00:00:39,160 --> 00:00:43,360 レシーバーのクラスからメソッドを探し始めます 11 00:00:43,800 --> 00:00:47,400 area が ColoredRectangle で見つかったら それを実行します。 12 00:00:47,720 --> 00:00:51,760 しかし area が見つからなければ アルゴリズムはスーパークラスを探します。 13 00:00:52,120 --> 00:00:54,520 Rectangle で area が見つかります。 14 00:00:55,640 --> 00:00:58,680 そのメソッドが レシーバーの上で実行されます。 15 00:01:00,680 --> 00:01:04,120 area メソッドが全く存在していない場合には 何が起こるでしょうか? 16 00:01:04,440 --> 00:01:07,120 探索が失敗したらどうなるのでしょうか? 17 00:01:08,040 --> 00:01:13,160 ここに例題があります。 coucou: メッセージが オブジェクト node 1 に送られます。 18 00:01:13,800 --> 00:01:16,640 coucou: は階層の中にありません。 19 00:01:16,960 --> 00:01:20,280 coucou: メッセージが node 1 に送られます。 20 00:01:20,600 --> 00:01:24,360 アルゴリズムは Node で coucou: を 見つけることに失敗します。 21 00:01:24,720 --> 00:01:27,960 次に、Object を探します。 coucou: はありません。 22 00:01:28,120 --> 00:01:29,440 この時点で 23 00:01:29,840 --> 00:01:34,880 Pharo のバーチャルマシンが doesNotUnderstand: メッセージを 24 00:01:35,320 --> 00:01:38,520 レシーバーの node 1 に送ります。 25 00:01:40,360 --> 00:01:43,320 DNU とは Does Not Understand です。 26 00:01:43,880 --> 00:01:47,600 バーチャルマシンはメッセージを 引数に変換します。 27 00:01:48,480 --> 00:01:50,520 これがその引数です。 「coucou: stef」 28 00:01:50,840 --> 00:01:53,800 もう一度、ステップを追っていきます。 29 00:01:54,240 --> 00:01:57,880 coucou: が node 1 に送られます。 そのクラスでマッチが試みられて 30 00:01:59,080 --> 00:02:01,040 そしてスーパークラスで試みられます。 31 00:02:01,200 --> 00:02:05,920 coucou: は見つかりません。 そこでメッセージ doesNotUnderstand: が 32 00:02:06,160 --> 00:02:08,200 オブジェクト node 1 に再送されます。 33 00:02:09,000 --> 00:02:12,640 アルゴリズムは doesNotUnderstand: メソッドを 34 00:02:12,880 --> 00:02:14,200 node 1 のクラスで探します。 35 00:02:14,800 --> 00:02:19,960 見つかりません。 アルゴリズムはそのスーパークラスから探します。 36 00:02:20,600 --> 00:02:22,680 ここにあります。 37 00:02:22,840 --> 00:02:27,080 doesNotUnderstand: メソッドが Object で見つかり、実行されます。 38 00:02:27,440 --> 00:02:29,480 つまり 39 00:02:29,960 --> 00:02:32,000 Object のあらゆるサブクラスで 40 00:02:32,360 --> 00:02:34,800 doesNotUnderstand: を実装して 41 00:02:34,960 --> 00:02:38,360 メッセージを理解できなかった場合の 特殊な振る舞いを 42 00:02:39,200 --> 00:02:43,640 起こすことができます。 43 00:02:44,480 --> 00:02:46,880 このスライドにその詳細を 44 00:02:47,200 --> 00:02:50,680 ステップ毎に示しています。 45 00:02:51,400 --> 00:02:54,280 doesNotUnderstand: は他のメッセージと同様に メッセージです。 46 00:02:54,560 --> 00:02:58,960 したがって、 DoesNotUnderstand: メソッドを実装して 47 00:02:59,400 --> 00:03:03,200 インスタンスがメッセージを理解できなかった時に 実行させることができます。 48 00:03:03,760 --> 00:03:05,160 このメカニズムは 49 00:03:05,800 --> 00:03:09,760 面倒な処理、たとえば 50 00:03:10,120 --> 00:03:12,880 プロキシや自動移譲のような 51 00:03:13,560 --> 00:03:17,800 あるオブジェクトが受け取ったメッセージを全て 52 00:03:17,960 --> 00:03:19,680 他のオブジェクトに送りたい時に使います。 53 00:03:19,840 --> 00:03:23,200 doesNotUnderstand 機構は そんなことに使われます。 54 00:03:24,040 --> 00:03:27,400 doesNotUnderstand:の デフォルトの実装は 55 00:03:27,560 --> 00:03:28,640 Object クラスにあります。 56 00:03:29,000 --> 00:03:32,200 その実装では例外を上げます。 57 00:03:33,000 --> 00:03:34,240 その例外は 58 00:03:35,080 --> 00:03:38,280 MessageNotUnderstood と呼ばれます。 59 00:03:38,640 --> 00:03:41,760 したがって、もしも Object クラスの DoesNotUnderstand: メソッドが実行されたら 60 00:03:41,920 --> 00:03:44,680 例外が上がります。 61 00:03:45,240 --> 00:03:49,600 つまりコードの中でその例外をキャッチできます。 62 00:03:49,920 --> 00:03:52,640 他の例外のキャッチと同じ方法で。 63 00:03:52,880 --> 00:03:57,520 例外は、理解されなかったメッセージの デバッガーを開きます。 64 00:03:58,040 --> 00:03:59,440 この例では 65 00:04:00,080 --> 00:04:02,640 また Node クラスに戻りますが 66 00:04:02,960 --> 00:04:07,120 sayHello メソッドが Node にあって coucou: メッセージを 67 00:04:07,600 --> 00:04:09,480 レシーバーつまり self に送ります。 68 00:04:10,760 --> 00:04:12,760 また、 welcome メソッドもあって 69 00:04:13,120 --> 00:04:16,280 sayHello メッセージを self に送ります。 70 00:04:16,680 --> 00:04:20,600 welcome メソッドでは 理解されなかったメッセージのコンテキストで 71 00:04:21,360 --> 00:04:23,280 特殊なハンドリングをします。 72 00:04:23,600 --> 00:04:28,600 もしメッセージが理解されなければ ハンドルされます。 73 00:04:28,760 --> 00:04:32,000 ここで、 sayHello が coucou: メッセージを self に送ります。 74 00:04:32,160 --> 00:04:34,280 coucou: はまだ未実装です。 75 00:04:34,880 --> 00:04:37,640 最終的に doesNotUnderstand: メソッドが 76 00:04:38,000 --> 00:04:40,920 実行されます。 77 00:04:41,560 --> 00:04:45,240 MessageNotUnderstood 例外が 上げられます。 78 00:04:46,120 --> 00:04:48,280 on:do: と続くこのコードが 79 00:04:48,680 --> 00:04:52,560 例外をキャッチするのに使われます。 Java の try/catch に似ています。 80 00:04:52,960 --> 00:04:56,800 このコースの続く講義で これらの例外について学びます。 81 00:04:57,880 --> 00:05:00,800 ここで重要なことは このコードが 82 00:05:00,960 --> 00:05:05,720 Java の catch と同じで 例外に対して実行されるということです。 83 00:05:06,640 --> 00:05:09,280 さあ、メッセージ welcome を 84 00:05:10,440 --> 00:05:11,840 node 1 に送ります。 85 00:05:12,000 --> 00:05:14,080 coucou: が実装されていないことが 判明して 86 00:05:14,520 --> 00:05:18,520 コンソールに「Something went wrong with the message.」と表示されます。 87 00:05:19,440 --> 00:05:20,640 これまででわかったことは 88 00:05:22,680 --> 00:05:27,240 探索アルゴリズムがメッセージにマッチした メソッドを見つけられなかった時には 89 00:05:27,560 --> 00:05:31,440 doesNotUnderstand: メッセージが 元のレシーバーに送られて 90 00:05:31,600 --> 00:05:33,760 元のメッセージが引数として渡されます。 91 00:05:34,360 --> 00:05:37,520 どんなクラスでも このメソッドを定義できます。 92 00:05:37,800 --> 00:05:41,840 Object クラスでのデフォルトの実装が 実行されると 93 00:05:42,080 --> 00:05:45,200 例外が上がります。 94 00:05:45,440 --> 00:05:47,400 MessageNotUnderstood 例外です。 95 00:05:47,560 --> 00:05:50,560 この例外をコードでキャッチすることも 96 00:05:50,720 --> 00:05:53,200 デバッグすることもできます。