素人老人が年甲斐もなく、モダンに仕立て直されたSmalltalk後継Pharoに突っ込んでます。今回は「Example」を読みながら、最初のクラスを定義してみようと思ったのです。ただただ文書に書いてある通りに入力すれば良いだけ、と高を括っていたら、結構ね、戸惑うことが多かったです。頭も固くなっているんじゃないか?自分。
※「ソフトな忘却力」投稿順 Index はこちら
※今回の動作確認は、Windows11上のWSL2の上のUbuntu24.04LTS上のPharo 10.0.0を使用しています。
最初のクラス、どれにしようか?
第35回で述べたとおり、Pharo様のお勉強リソース充実してます。手持ちの御本まで含めると練習候補はいろいろありすぎ。そのなかでこれだね、と思ったのが以下ドキュメントのChapter 5です。理由は入力量少なくでお楽そうだったから。以下Chapter5部分を単にExampleと唱えます。
Pharo by Example 9 – 2022 Edition
ほぼほぼ上記に対応している動画が以下のサイトの第1週第11回付近にあります。上の文書読んでいて戸惑ったところは動画で解決。あざーす。
この実習は、カウントアップ、ダウン、初期化程度のことができるカウンタを作ってみろい、ということであります。ただね、一言、言わせていただくと、Pharo by Example 9の説明、クラスを作り始めたかと思うと、ユニットテストの作成に飛び、はたまたソース管理システムにも言及しという感じです。「テスト駆動設計」を標榜されているので、当然といえば当然なのですが、初心者にはアチコチ飛び回るのはキツイです。とくに忘却力の老人には。ということで勝手ながら、ともかくクラスを作って走らせる、という一点突破の演習としました。手抜きだな。
まずは新しいパッケージを作るところから
全てのオブジェクトは階層構造にオーガナイズされているシステムなので、まずは「練習場所」を確保しておかんとなりません。
例によって、System Browserを開き、一番左のpackageペインというところで右クリックしてメニューを出し、New packageしてみます。
ベタな名前の場所を確保いたしました。この配下にゴタゴタしたものを追加しても、他に影響はない筈。
つづいて新たなクラスを追加します。上のSystem Browserの下の方だけ表示してます。すでに「テンプレート」的な定義が表示されているのでそれを真似して入力していきます。以下は入力終わってAccept(バイトコードにコンパイルされるみたい)するところです。
実際には、最初に書いてあるObjectという根っこのオブジェクト(レシーバー)に諸般の引数を引き連れたメッセージを送っているということみたいです。何につけPharo様は首尾一貫。
なお、Classにはコメントつけた方がいいようですが、まだ入力されてません。そのため、Pharo様がいろいろお怒りみたいです(下の方。)
上みると、中ほどにCommentというタブが2つもあるのですが、左が簡易なマークアップ言語でコメントを入力するタブで、右がそれをレンダリングしてカッコよく表示してくれているタブです。
左のタブを開くとこんな感じです。やはりテンプレート的なものが既に準備されています。
どうも、Pharo様は「無理やり強制しないけど、ツールとテンプレで、一本筋を通していく」スタイルみたいです(個人の感想っす。)
筋といえば、コメントをセーブしようとすると以下のようにAuthor Identificationとて名前の入力を求められます。悪いことはデキんよ。
テキトーにコメント入力した後のレンダリング画面が以下に。
なお、一番右端のUML-Classタブが気になるので開いてみました。
まだクラス一つだけなので、素っ気ないですが、確かにUMLの箱が描かれとります。これが増えていくのか? 至れり尽くせりだな。
メソッドの定義に戸惑う
System Browserでメソッドは一番右端です。メソッドのペインとクラスのペインの間に「プロトコル」のペインがあるのですが、とりあえずここに積極的に何かいれなくても「よきに計らってくれる」みたいです。インスタンスメソッドを定義するとて、instance sideをクリッとやると、下の方にメソッドのテンプレートが表示されてました。
上記を編集し、猪口才にもコメントも抜きの最初のメソッド定義(だってExampleでも書いてなかったし。)
CTRL+Sで定義したら、勝手にaccessingというプロトコルに分類されてました。しかしここで躓きました。上記のように countという、インスタンス変数countの内容を返すだけ(ゲッタ)は定義できたのですが、Exampleによるとなんやらオートマチックにセッタとなる count: を定義してくれるみたいなこと書いてあります。やってみたのですが、上手く行きません。初心者はパニックよ。でもま、MOOCの動画みたらば、フツーに手入力でセッタである count: を定義していたので真似っこ。
Exampleではこの辺から、ユニット・テストやらソース管理やらに突入するのですが、忘却力の老人は覚えきれないので、クラス定義を完成させます。コメント文に書いたとおり、APIメソッドが3つ、increment、decrement、startAtを端から定義していきます。
なお、Exampleでは、コメントを書くところでは初期化メソッド名を startAt と綴っているのに、実際に定義する段では、startingAt としてました。コマケー話なんだが。
なお、初期化メソッドの startAt だけはインスタンスでなく、クラスメソッドです。クラス自身である MyCounterにこれを送ることでインスタンスが返ってきます。定義の際は Inst. sideからClass sideに切り替えてから定義っと。
ひととおりクラスができたので、Playgroundから実行。まず、インスタンスを作るのに new をして、出来たインスタンスにセッタである count:で3を送り込むスタイルで、デクリメント、デクリメント、インクリメントした結果が以下に。
2が返ってきました。
4で初期化したインスタンスを1回インクリメントしたから5ね。
Save and quit するまえに、MytrainingRoomをテキスト形式でもセーブしておきました。こんな感じ。
これで少しは覚えたか?いやいや年寄の記憶力は甘くないぜ。