こんにちは。このセッションでは クラスメソッドについてお話します。
Pharo では、全てのものはオブジェクトで
オブジェクトにメッセージを送ることができます。
つまり、これら2つの情報を基にすれば
クラスもオブジェクトであり
したがってクラスに情報 つまりメッセージを送ることができます。
例題を2つ示します。
Time now では、Time クラスという オブジェクトに now メッセージを送ります。
そして今の時刻が返ってきます。
つまり、now メッセージを
クラスである Time オブジェクトに送ります。
すると今の時刻が送り返されます。
同じように、クラスである Date オブジェクトに todayメッセージを送ると
日付が返ってきます。
もう3つ例があります。
FileLocator クラスに workingDirectory メッセージを送ると
現在のパスが返ってきます。
つまり実行されているファイルのディレクトリパスです。
2つ目の例は
ZnEasy オブジェクトに getPng: メッセージを送ります。
引数として png ファイルの URL を付けて。
すると、ダウンロードされた png ファイルを 返します。
3つ目の例は
これまたクラスである ZnServer に startDefaultOn: メッセージを
ポート番号を引数にして送ります。
これは HTTP サーバを立ち上げます。
これら3つのケースでは 1つのクラスに1つのメッセージを送ります。
どうやってクラスメソッドを実装するのでしょう？
クラスを選択して
class ボタンを押すことで インスタンス側ではなくクラス側に
メソッドを実装したいということを示します。
あとはいつも通りにメソッドを実装します。
つまり today メソッドは Date クラスの
クラス側に実装されています。
クラス側のメソッドで ありがちな間違いというものがあります。
ここでは withValue: メッセージを
Counter クラスに送ることで
引数の値がセットされた 新しいカウンターを得たいのです。
つまり
Counter withValue: 10 は 値が10で始まるカウンターを返します。
もしこの表現式を評価したら Counter という値が得られます。
新しいカウンターではなく。
つまり、このクラスのインスタンスではなく そのクラス自身が得られます。
なぜこんな間違いが起こるのでしょう？ 何が問題なのでしょう？
問題は、メソッドはデフォルトでは self を返すということです。
つまり、もし返り値を明示しなければ メソッドは self を返します。
したがって、この上のほうのコードは 下のほうのコードと等価です。
この場合、self は Counter クラスです。
したがってメソッドはそのクラス自身を返します。 今まさに作ったばかりのインスタンスではなく。
この問題を直すには
単にキャレット（ ^ ）を
self new の前に付けるだけです。
まとめると クラスはオブジェクトです。
あらゆるオブジェクトにメッセージを送ることができるので あらゆるクラスにもメッセージを投げることができます。
それらのメッセージに対応するメソッドを実装するには
クラスを選択して class ボタンを押す必要があります。
大部分のクラスメソッドは 新しいインスタンスを作りますが
それだけでなく、他のこともします。
クラスメソッドの他の利用法が Pharo の中にたくさん見つかります。
クラスメソッドは他のメソッドと同じで
特別なルールはありません。
メソッド探索は全く同じ方法で行われます。
次週にそれを学びます。