WEBVTT

00:00:00.520 --> 00:00:03.800 align:middle
こんにちは。このクラスでは
Pharo の強力な例外をお見せします。

00:00:03.960 --> 00:00:06.400 align:middle
概要をお見せします。

00:00:06.600 --> 00:00:09.160 align:middle
例外で何ができるのでしょう？
例外から復帰(resume)できます。

00:00:09.520 --> 00:00:11.840 align:middle
再実行(restart)もできます。
新しい例外としてシグナルします。

00:00:12.000 --> 00:00:16.240 align:middle
例外を最初に使うための
実用上役にたつものだけを

00:00:16.400 --> 00:00:17.840 align:middle
お見せしましょう。

00:00:18.000 --> 00:00:20.840 align:middle
しかし、これが全てだというのでは
ありません。

00:00:21.000 --> 00:00:24.600 align:middle
例外には 2 種類あります。
致命的なものが多いエラーと

00:00:24.760 --> 00:00:27.680 align:middle
通知です。
通知は要らないということができ

00:00:27.840 --> 00:00:29.160 align:middle
参考のためにあります。

00:00:30.320 --> 00:00:32.800 align:middle
もし、例外についての

00:00:32.960 --> 00:00:35.800 align:middle
完璧なリファレンスが必要であれば

00:00:35.960 --> 00:00:39.640 align:middle
この書籍 Deep Into Pharo の
章が 1 つまるまるあります。

00:00:39.800 --> 00:00:45.040 align:middle
この Mooc のウェブサイト上で
無料で提供されています。

00:00:45.600 --> 00:00:50.640 align:middle
では何を学ぶのかというと
例外を挙げて捕捉することと

00:00:50.800 --> 00:00:54.400 align:middle
普段から使うことができる
便利なヘルパーメソッドです。

00:00:54.960 --> 00:00:55.800 align:middle
基本的には

00:00:56.000 --> 00:00:58.440 align:middle
この講義でやることは全て
このページに書いてあります。

00:00:58.800 --> 00:01:02.360 align:middle
例外を捕捉するための
ハンドラをインストールします。

00:01:02.520 --> 00:01:03.480 align:middle
例外をシグナルして

00:01:03.640 --> 00:01:08.280 align:middle
2 つの便利なメッセージをやります。
ensure: と ifCurtailed: です。

00:01:09.400 --> 00:01:11.280 align:middle
では見てみましょう。

00:01:11.840 --> 00:01:14.680 align:middle
例外を捕捉したいとしましょう。

00:01:14.840 --> 00:01:16.880 align:middle
on:do: メッセージを使います。

00:01:17.040 --> 00:01:20.120 align:middle
ブロックを用意しておいて何かしていて

00:01:20.280 --> 00:01:23.160 align:middle
例外が起きたらどうなるでしょう。

00:01:23.320 --> 00:01:27.280 align:middle
ここで something をします。
例外が引数として渡されます。

00:01:27.920 --> 00:01:31.520 align:middle
ゼロ除算の例を見てみます。

00:01:31.680 --> 00:01:34.960 align:middle
7 を 0 で割ると

00:01:35.600 --> 00:01:38.120 align:middle
ゼロ除算で何が起こるかというと

00:01:38.280 --> 00:01:41.640 align:middle
ゼロ除算があるぞ！と言います。

00:01:41.800 --> 00:01:47.160 align:middle
ここで注目することは
この例外クラスのインスタンスが

00:01:48.360 --> 00:01:49.840 align:middle
引数として渡されて

00:01:50.000 --> 00:01:52.600 align:middle
例外に質問したりメッセージを送ることが
できるということです。

00:01:52.760 --> 00:01:54.680 align:middle
なぜなら、Pharo では例外は
オブジェクトだからです。

00:01:54.840 --> 00:01:56.600 align:middle
例外の中でメッセージを送って

00:01:56.760 --> 00:02:00.400 align:middle
何かをして、0 となります。

00:02:00.800 --> 00:02:02.920 align:middle
では、どうやって例外を起こすのでしょう？

00:02:03.240 --> 00:02:07.400 align:middle
基本的に、例外を生成して
それに signal メッセージを送ります。

00:02:07.560 --> 00:02:10.840 align:middle
ここでは、警告を与えたい場合には
Warning new

00:02:11.000 --> 00:02:15.240 align:middle
例外を生成して、カスタマイズして
メッセージを設定します。

00:02:15.400 --> 00:02:16.760 align:middle
そして signal メッセージを送ります。

00:02:16.920 --> 00:02:21.000 align:middle
著者名を尋ねる例外
AuthorNameRequest クラスがあり

00:02:21.160 --> 00:02:23.000 align:middle
メソッドを書けば

00:02:23.160 --> 00:02:24.720 align:middle
他の API として使えます。

00:02:24.880 --> 00:02:28.240 align:middle
AuthorNameRequest がこの API を
定義するからです。

00:02:28.400 --> 00:02:30.440 align:middle
そこで 文字列 'Stef' を渡して
signal します。

00:02:30.600 --> 00:02:33.080 align:middle
通常は

00:02:33.240 --> 00:02:38.040 align:middle
クラスが signal するショートカットを
提供して、生成せずに済むようにします。

50 align:middle
00:02:38,200 --> 00:02:41,640
OutOfMemory はクラスです。
このクラスに signal メッセージを送ります。

00:02:41.800 --> 00:02:44.800 align:middle
通常は警告文をつけて
Warning new なんとかかんとか、とはしません。

00:02:44.960 --> 00:02:48.840 align:middle
Warning signal: として文字列をつけます。
そのほうが短く書けます。

00:02:49.000 --> 00:02:51.160 align:middle
ただし例外によります。

00:02:51.720 --> 00:02:56.800 align:middle
ユニットテストをするアジャイルな
プログラミングや

00:02:57.000 --> 00:03:00.080 align:middle
テスト駆動なプログラミングで

00:03:00.240 --> 00:03:04.440 align:middle
例外が起こったことをどうやって
テストしたら良いでしょう？

00:03:04.600 --> 00:03:08.840 align:middle
shouldnt:raise や should:raise:
を使います。

00:03:09.000 --> 00:03:10.440 align:middle
一緒に読んでみましょう。

00:03:10.600 --> 00:03:13.640 align:middle
ここで

00:03:13.800 --> 00:03:15.840 align:middle
2 月の日付を生成する時に

00:03:16.000 --> 00:03:18.240 align:middle
SubscriptOutOfBounds 例外は

00:03:18.400 --> 00:03:21.640 align:middle
挙がって欲しくない、と書きます。

00:03:21.800 --> 00:03:25.200 align:middle
では、13 月の日付を生成する時には

00:03:25.360 --> 00:03:29.040 align:middle
エラーが発生しなければならない
とします。

00:03:29.200 --> 00:03:32.240 align:middle
まあ普通はそんな日付はないですね。

00:03:32.400 --> 00:03:35.560 align:middle
そこで should:raise: を使います。

00:03:35.720 --> 00:03:37.080 align:middle
つまり

00:03:37.240 --> 00:03:40.960 align:middle
13 月の日付を作るとエラーになる
ということです。

00:03:41.120 --> 00:03:44.000 align:middle
こうすることで例外についての

00:03:44.160 --> 00:03:46.280 align:middle
ユニットテストを書くことができます。

00:03:46.440 --> 00:03:48.400 align:middle
細かなことではありますが

00:03:48.560 --> 00:03:51.120 align:middle
これら 2 つのヘルパーメソッドを
知ることは重要です。

00:03:52.120 --> 00:03:54.360 align:middle
Pharo での例外には

00:03:54.560 --> 00:03:56.040 align:middle
Error があります。

00:03:56.200 --> 00:03:59.360 align:middle
メッセージを理解できない
添字エラー、ゼロ除算など。

00:03:59.520 --> 00:04:03.280 align:middle
Halt があります。
デバッグする時に見ることになります。

00:04:03.440 --> 00:04:04.840 align:middle
ブレークポイントを置いて

00:04:05.000 --> 00:04:07.480 align:middle
システムの実行を止めることができます。

00:04:07.640 --> 00:04:10.760 align:middle
Notification があります。
致命的でないものです。

00:04:10.920 --> 00:04:15.400 align:middle
例えば 廃止（Deprecation）です。
このメソッドは使うな。他のを使えと。

00:04:15.560 --> 00:04:16.880 align:middle
警告やタイムアウトもです。

00:04:17.040 --> 00:04:19.760 align:middle
おもしろいのは

00:04:19.920 --> 00:04:22.240 align:middle
UnhandledError です。

00:04:22.400 --> 00:04:25.240 align:middle
これがデバッガーを起動します。

00:04:25.400 --> 00:04:28.680 align:middle
通常は UnhandledError は使いませんが
UnhandledError も Error の一種だと

00:04:28.840 --> 00:04:31.360 align:middle
いうことは知っておいてください。

00:04:32.080 --> 00:04:34.720 align:middle
例外は本物のオブジェクトです。

00:04:34.920 --> 00:04:37.920 align:middle
doesNotUnderstand: メッセージが

00:04:38.120 --> 00:04:41.600 align:middle
ProtoObject でどう定義されているか
Pharo ブラウザで見ることができます。

00:04:41.760 --> 00:04:43.920 align:middle
そこでは
MessageNotUnderstood new

00:04:44.080 --> 00:04:48.960 align:middle
message: と receiver: を送って
signal します。

00:04:49.120 --> 00:04:53.480 align:middle
この例外は
Point new strangeAndBizarre で起こります。

00:04:53.640 --> 00:04:56.160 align:middle
strangeAndBizarre メッセージは
知らないので。

00:04:56.320 --> 00:04:57.920 align:middle
そこで例外を作ります。

00:04:59.440 --> 00:05:01.880 align:middle
Deprecationは 例えば

00:05:02.040 --> 00:05:05.040 align:middle
まだ成長している API を使っていて

00:05:05.200 --> 00:05:08.200 align:middle
もう有効ではないと
Pharo が決めた場合です。

00:05:08.360 --> 00:05:09.520 align:middle
実際…

00:05:09.680 --> 00:05:15.000 align:middle
Pharo では deprecated:on:in:
を使います。

00:05:15.160 --> 00:05:17.360 align:middle
分かりやすい例を選んでみました。

00:05:17.520 --> 00:05:19.680 align:middle
menuItem title:
は何を言っているかというと

00:05:19.840 --> 00:05:23.880 align:middle
title: のかわりに
addTitle: を使えということです。

00:05:25.200 --> 00:05:26.960 align:middle
どう実装されているかというと

00:05:27.120 --> 00:05:30.480 align:middle
deprecated:... は

00:05:30.640 --> 00:05:33.960 align:middle
Deprecation という

00:05:34.120 --> 00:05:35.280 align:middle
例外を生成して

00:05:35.440 --> 00:05:39.960 align:middle
その例外オブジェクトに
メソッドや説明を与えて

00:05:40.120 --> 00:05:42.680 align:middle
signal します。

00:05:42.840 --> 00:05:46.800 align:middle
deprecation も　messageNotUnderstood も
例外で、例外を生成して挙げているということです。

00:05:48.320 --> 00:05:52.080 align:middle
これは細かいことになりますが
例外の集合 ExceptionSet もあります。

00:05:52.240 --> 00:05:54.960 align:middle
ZeroDivide や Warning が起こったら
という記述ができます。

00:05:55.120 --> 00:05:59.080 align:middle
あるいはコンマで区切ることで

00:05:59.240 --> 00:06:02.800 align:middle
例外の集合を生成することができます。

00:06:02.960 --> 00:06:06.200 align:middle
これを使って
これらの例外に反応する、と書けます。

00:06:06.360 --> 00:06:11.000 align:middle
滅多に使われません。
一通り見せるために説明しています。

00:06:11.720 --> 00:06:14.840 align:middle
では、より頻繁に使われる

00:06:15.520 --> 00:06:17.320 align:middle
便利なメソッドを見てみましょう。

00:06:17.480 --> 00:06:20.680 align:middle
ある表現式について
プログラムがその手前で失敗しても。

00:06:20.840 --> 00:06:24.360 align:middle
その表現式が必ず実行されるとどうやって
確証を得ることができるでしょうか？

00:06:24.520 --> 00:06:27.320 align:middle
ensure: を使います。
ensure: は

00:06:27.480 --> 00:06:29.120 align:middle
何かをやっていて

00:06:29.280 --> 00:06:33.520 align:middle
別のブロックが実行されることを
保証します。

00:06:33.680 --> 00:06:38.800 align:middle
とても強力です。
例えば自動的にファイルをクローズできます。

00:06:39.400 --> 00:06:43.160 align:middle
Pharo のプロファイラーの
spyOn: を見てみましょう。

00:06:43.320 --> 00:06:46.680 align:middle
プロファイリングを開始して

00:06:46.840 --> 00:06:49.640 align:middle
プロファイリング対象の
このブロックを実行します。

00:06:49.800 --> 00:06:52.160 align:middle
そしてプロファイルを停止することを
保証します。

00:06:52.320 --> 00:06:55.200 align:middle
たとえプロファイル対象として渡された
ブロックがエラーを起こしても。

00:06:55.400 --> 00:06:57.480 align:middle
もう1つ、とても便利なヘルパーがあります。

00:06:57.680 --> 00:07:00.000 align:middle
ある表現式が

00:07:00.160 --> 00:07:04.680 align:middle
プログラムが失敗した時だけ
実行されることを保証します。

00:07:05.440 --> 00:07:09.320 align:middle
何か変なことが起こったら

00:07:09.480 --> 00:07:13.880 align:middle
これを実行する、というものです。

00:07:14.040 --> 00:07:16.680 align:middle
wait の例は低レベルのもので

00:07:16.840 --> 00:07:20.800 align:middle
プロセッサーのスケジューリングを
変えるものです。

00:07:21.520 --> 00:07:26.800 align:middle
システムがセマフォをスケジュールして

00:07:26.960 --> 00:07:30.320 align:middle
何か不具合があったら

00:07:30.480 --> 00:07:32.520 align:middle
システムがスケジューラから

00:07:32.680 --> 00:07:36.160 align:middle
外すことを保証します。

00:07:36.320 --> 00:07:40.080 align:middle
これらのメソッドは
とても手軽でパワフルです。

00:07:40.480 --> 00:07:45.280 align:middle
メソッド探索がどう動くかを説明する

00:07:45.440 --> 00:07:47.120 align:middle
スライドを

00:07:47.320 --> 00:07:48.480 align:middle
お見せしましたが

00:07:48.680 --> 00:07:50.440 align:middle
ここでは...

00:07:50.600 --> 00:07:53.600 align:middle
Pharo での例外では

00:07:53.760 --> 00:07:59.160 align:middle
別の結果を返したり
再実行したりできます。

00:07:59.320 --> 00:08:01.320 align:middle
プログラムの実行を変更して

00:08:01.480 --> 00:08:05.320 align:middle
例外が起こらなかったかのように
動くようにすることが

00:08:05.480 --> 00:08:07.800 align:middle
resume を使ってできます。

00:08:07.960 --> 00:08:11.600 align:middle
この例外はこのレベルでは扱いたくないから

00:08:11.760 --> 00:08:13.280 align:middle
より上位で扱ってほしい、ということが

00:08:13.440 --> 00:08:14.920 align:middle
例外を pass することで可能です。

00:08:15.080 --> 00:08:18.840 align:middle
古い例外を新しい例外で置き換えることも

00:08:19.000 --> 00:08:19.880 align:middle
resignal でできます。

00:08:20.040 --> 00:08:23.520 align:middle
これが必要な時には
あなたは何をやっているか分かっているでしょう。

00:08:23.680 --> 00:08:28.400 align:middle
この章を読んで
こういうことができるこということを

00:08:28.600 --> 00:08:30.520 align:middle
知っておいてください。

00:08:30.720 --> 00:08:33.600 align:middle
例外から別の返り値を返す時は
return: を使います。

00:08:33.760 --> 00:08:38.160 align:middle
これを見てわかるように
この値を返すブロックを渡して

00:08:38.320 --> 00:08:41.400 align:middle
例外を挙げると、最終的には

00:08:41.560 --> 00:08:45.400 align:middle
ブロックが返したこの値が返ってきます。
これが return: です。

00:08:45.560 --> 00:08:48.400 align:middle
では、resume: は何かというと

00:08:48.560 --> 00:08:50.920 align:middle
resume: では

00:08:51.080 --> 00:08:54.240 align:middle
ここで起こされた例外について

00:08:54.400 --> 00:08:58.560 align:middle
resume: すると

00:08:58.720 --> 00:09:02.120 align:middle
このハンドラで与えた値ではなく
次の値になります。

00:09:02.280 --> 00:09:07.360 align:middle
例外が発生した箇所から継続するのです。
なので、ここから再開します。

00:09:07.520 --> 00:09:10.120 align:middle
そしてこの値が得られます。

00:09:11.240 --> 00:09:14.000 align:middle
ではまとめます。

00:09:14.200 --> 00:09:16.960 align:middle
Pharo の例外は強力です。
ええ、いいですね。

00:09:17.120 --> 00:09:20.840 align:middle
とてもシンプルな API があります。
例外を挙げる signal と

00:09:21.000 --> 00:09:22.720 align:middle
例外を捕捉する on:do: と

00:09:22.880 --> 00:09:27.880 align:middle
この表現式が必ず実行されるように
保証する ensure: と

00:09:28.040 --> 00:09:30.280 align:middle
問題が発生するか否かで

00:09:30.440 --> 00:09:32.720 align:middle
発生した時に実行する ifCurtailed:

00:09:32.880 --> 00:09:35.720 align:middle
doSomething の中で問題が発生したら
onProblem を実行します。

00:09:35.880 --> 00:09:38.760 align:middle
例外を使い始めるために必要なことは
これで全てです。

