1 00:00:00,400 --> 00:00:01,600 こんにちは、みなさん。 2 00:00:01,760 --> 00:00:05,840 この講義ではクラスメソッドに注目します。 3 00:00:06,320 --> 00:00:08,320 前に見た通り 4 00:00:08,520 --> 00:00:12,840 クラスメソッドは 他のメソッド同様の通常のメソッドです。 5 00:00:13,520 --> 00:00:17,440 一般に、新しいインスタンスを作るために 使いますが 6 00:00:17,760 --> 00:00:19,760 他のことにも使われます。 7 00:00:20,200 --> 00:00:24,080 クラスメソッドの使い方について 2つの例を見ましょう。 8 00:00:24,720 --> 00:00:28,280 仮に、コンピュータプログラムで 9 00:00:28,440 --> 00:00:30,840 これらの行をパースしたいとします。 10 00:00:32,120 --> 00:00:34,800 これらの行は構造を作っています。 11 00:00:36,000 --> 00:00:39,720 感嘆符(!)で始まる行は 12 00:00:40,120 --> 00:00:42,040 タイトルとして読み込まれます。 13 00:00:42,480 --> 00:00:47,720 ダッシュ(-)で始まる行は リストのアイテムです。 14 00:00:49,240 --> 00:00:51,920 1つより多くのダッシュで始まる行は 15 00:00:52,120 --> 00:00:54,760 リストのサブアイテムです。 16 00:00:55,680 --> 00:00:58,000 他の場合は、段落です。 17 00:00:58,800 --> 00:01:01,560 これらを入力とするプログラムで 18 00:01:03,080 --> 00:01:05,640 DocumentItem のサブクラスの 19 00:01:05,800 --> 00:01:07,960 インスタンスを作ります。 20 00:01:10,080 --> 00:01:13,080 また、このプログラムの設計として 21 00:01:13,280 --> 00:01:16,600 DocumentItem の各サブクラスが 22 00:01:16,760 --> 00:01:17,880 行をパースする責任を持っていて 23 00:01:18,040 --> 00:01:21,640 与えられた行について canParse: を決めることにします。 24 00:01:21,800 --> 00:01:26,680 ここの canParse: メソッドでは 1行のテキストを渡します。 25 00:01:27,000 --> 00:01:30,440 その行が感嘆符で始まっていたら 26 00:01:30,600 --> 00:01:32,920 canParse: メソッドは true を返します。 27 00:01:33,080 --> 00:01:35,840 その行は、SectionTitle クラス に属します。 28 00:01:36,440 --> 00:01:37,920 LiteItem クラスでは 29 00:01:38,640 --> 00:01:43,920 canParse: メソッドはダッシュで始まる行に true を返します。 30 00:01:44,760 --> 00:01:48,400 そして、この canParse: は常に true を返します。 31 00:01:49,240 --> 00:01:54,320 考え方としては、クラスを1つ1つ見ていって 32 00:01:54,920 --> 00:01:58,120 与えられた行をパースできるクラスを見つけ次第 33 00:01:58,840 --> 00:02:03,480 そのクラスを使って、その行をパースした 新しいインスタンスを作る、ということです。 34 00:02:04,600 --> 00:02:06,840 それが canParse: メソッドのゴールです。 35 00:02:07,000 --> 00:02:11,840 newFromLine: メソッドは 1 行のテキストを引数として取って 36 00:02:12,960 --> 00:02:17,560 その行を表すインスタンスを返します。 37 00:02:17,920 --> 00:02:22,920 newFromLine: メッセージが SectionTitle クラスに送られて 38 00:02:23,200 --> 00:02:27,120 感嘆符で始まる一連の文字が渡されたら 39 00:02:27,520 --> 00:02:31,880 newFromLine: メソッドは SectionTitle クラスのインスタンスを返します。 40 00:02:32,360 --> 00:02:33,760 こんな風に動くようにします。 41 00:02:34,080 --> 00:02:36,880 Parser クラスがすることは 42 00:02:37,040 --> 00:02:39,680 DocumentItem のサブクラスの中から 43 00:02:40,000 --> 00:02:42,160 与えられた行を担当するものを探します。 44 00:02:42,520 --> 00:02:46,360 Parser は documentClasses という メソッドを持っています。 45 00:02:47,320 --> 00:02:51,720 そのメソッドは DocumentItem の 46 00:02:52,160 --> 00:02:53,520 サブクラスのリストを返します。 47 00:02:53,840 --> 00:02:58,040 これらのクラスを含む コレクションを返します。 48 00:02:58,640 --> 00:03:02,320 DocumentItem に allSubclasses メッセージを送ります。 49 00:03:02,480 --> 00:03:05,800 allSubclasses メソッドは Pharo システムに 既に存在しています。 50 00:03:05,960 --> 00:03:09,160 与えられたクラスの サブクラスのリストを返します。 51 00:03:09,640 --> 00:03:13,000 このメッセージの結果 52 00:03:13,160 --> 00:03:16,440 SectionTitle と ListItem と Text を含むコレクションが得られます。 53 00:03:17,960 --> 00:03:20,520 このコレクションを優先順位によって 並べておきます。 54 00:03:20,680 --> 00:03:24,400 そうすることで、Text クラスが最後に なるようにします。 55 00:03:24,680 --> 00:03:27,960 というのも、Text クラスの canParse: メソッドは 常に true を返すからです。 56 00:03:28,120 --> 00:03:31,640 Text クラスはどんな行でも パースできてしまいます。 57 00:03:32,960 --> 00:03:36,080 他のクラスを試したあとで、 Text クラスを試します。 58 00:03:36,240 --> 00:03:39,520 そのために優先順位という概念を使います。 59 00:03:41,160 --> 00:03:44,960 見ての通り、多くのメソッドに 下線が引かれています。 60 00:03:45,240 --> 00:03:48,760 メソッドに下線を引かれていると 61 00:03:49,160 --> 00:03:51,720 それはクラスメソッドだということを 示しています。 62 00:03:52,040 --> 00:03:56,240 これらのメソッドを実行するためには メッセージをクラスに送らなければなりません。 63 00:03:56,480 --> 00:04:01,400 canParse: メソッドを SectionTitle クラスに送って 64 00:04:01,760 --> 00:04:05,840 SectionTitle クラスが与えられた行を パースできるかどうか見なければなりません。 65 00:04:08,240 --> 00:04:12,560 Parser クラスの parse: メソッドは 行を引数として受け取ります。 66 00:04:12,960 --> 00:04:18,760 DocumentItem の全てのサブクラスから その行をパースできるクラスを探します。 67 00:04:19,040 --> 00:04:22,600 見つかれば そのクラスのインスタンスを作ります。 68 00:04:24,200 --> 00:04:28,600 detect: をコレクションに送ることで 69 00:04:29,160 --> 00:04:33,520 そのコレクションの要素の中から 述語を満たすものを得ます。 70 00:04:34,400 --> 00:04:38,920 さて、クラスメソッドを使う もう 1 つの例を見てみましょう。 71 00:04:39,320 --> 00:04:43,800 コマンドラインの引数をどのように扱っているか 見てみましょう。 72 00:04:44,480 --> 00:04:48,160 ここでは 引数を受け取って 73 00:04:49,040 --> 00:04:52,960 処理を変える引数を見つける プログラムを見ていきます。 74 00:04:53,360 --> 00:04:57,160 最初の引数はアクションが実行されることを示しています。 75 00:04:57,680 --> 00:05:02,080 プログラムの設計として アクションの種類ごとに 1つのクラスを持つようにします。 76 00:05:02,400 --> 00:05:06,000 eval アクションは1つのクラスで表現されます。 77 00:05:06,360 --> 00:05:08,160 EvaluateCommandLineHandler です。 78 00:05:09,920 --> 00:05:13,800 eval が引数として現れた時に どんなアクションが実行されるでしょうか? 79 00:05:14,440 --> 00:05:17,000 実行するのは… 80 00:05:17,280 --> 00:05:21,120 この一連の文字列が Pharo のコードとして解釈されて 81 00:05:21,560 --> 00:05:24,040 その表現式の結果が返されます。 82 00:05:24,680 --> 00:05:27,440 3628800 が 10 factorial の結果です。 83 00:05:27,920 --> 00:05:29,440 これは 84 00:05:30,360 --> 00:05:32,920 CommandLineHandler クラス を使って実装されています。 85 00:05:33,960 --> 00:05:36,440 EvaluateCommandLineHandler は 86 00:05:36,920 --> 00:05:41,480 eval の処理を担当するサブクラスです。 87 00:05:41,800 --> 00:05:45,560 eval がコマンドラインの 最初の引数として送られたら 88 00:05:45,720 --> 00:05:47,560 このクラスが処理しなければなりません。 89 00:05:48,680 --> 00:05:52,560 isReponsibleFor: メソッドが true を返すのは 90 00:05:53,200 --> 00:05:54,960 サブクラスが 91 00:05:55,120 --> 00:05:59,920 このコマンドラインを処理する能力が ある場合です。 92 00:06:01,400 --> 00:06:02,760 その背後には 93 00:06:03,240 --> 00:06:07,640 前の例で見たのと同じメカニズムがあります。 94 00:06:08,080 --> 00:06:13,160 もう1度言いますが、クラスメソッド そしてクラスへのメッセージ送信は 95 00:06:14,400 --> 00:06:16,800 インスタンスを作ること以外の仕事にも 使われます。 96 00:06:17,600 --> 00:06:21,480 この講義ではクラスメソッドの 2つの利用例を見ました。 97 00:06:22,200 --> 00:06:26,360 クラスメソッドは多くの場合 新しいインスタンスを作るために使われます。 98 00:06:26,680 --> 00:06:29,320 しかし、他の使い方もあります。