->
->
->
open morphic project 中を2回クリック Main Window クリック マウスをクリックして、下のメニューを出し、keep this menu up をクリックして、常時、メニューが表示される ようにしよう。また、open... から browser をクリックして、System Browser を表示しよう。 コマンド入力に使う作業スペースの Workspace 、出力である Transcript も表示しよう。 なお、ウィンドウサイズは、ウィンドウの周りの線や、Browser の pane の仕切りの線の所にマウスを持って 行くと小さな黄色の丸が出るので、それをドラッグすれば良い。ウィンドウのアイコン化、クローズは、ウィンドウの 右、左上のO、Xマークで行う。ウィンドウの移動は、タイトル部をドラッグして行う。 ->
->
->
keep this menu up / open... System browser
Workspace / Transcript ●カテゴリの追加、クラスの追加 さて、カテゴリを追加する。System Browser の第1Pane(カテゴリー)にマウスを持っていきクリックする。 ”add item...”を選択すると、カテゴリー名の入力ウィンドウが出るので”My Stuff”とする。 System Browser の左にスクロールバーがあるので、それをドラッグして一番下まで行くと、カテゴリー My Stuff がある(ハイライトされている筈)ので、これを選択する。下のコードペインには、テンプレートが 表示されているので、これを求める BankAccount クラスに書き替える。
![]()
コードペインに下記のコード定義を入力する。 Object subclass: #BankAccount instanceVariableNames: 'balance' classVariableNames: '' poolDictionaries: '' category: 'My Stuff'
Object subclass: #BankAccount ->BankAccountは Object のサブクラス instanceVariableNames: 'balance' ->インスタンス変数名 ’balannce’残高 classVariableNames: '' ->クラス変数名 無し poolDictionaries: '' ->プール辞書 無し category: 'My Stuff' ->カテゴリは”My Stuff” この記述は、Object に subclass: #BankAccount 以下のメッセージを送っていることでもある。 Object は class のインスタンスなので、super にメッセージがわたされて処理される。
入力中はコードペインの外周が赤色になる。終わったら accept(Alt-s) すると、色が黒に戻る。上の第2paneに BankAccount
がハイライトされて表示される。
●オブジェクトの生成とインスペクト
Workspace を open... メニューから開き、下記のステートメントを入力する。
この内容を Ctrl-c でコピーし、Squeak では Alt-v でペーストしても良い。原文では、左矢印とかを説明し、またブラウザ
で原文を見るとアンダースコアになっていたりする。紛らわしいので説明には、代入に”:=”のみ使う。
b:= BankAccount new.
b inspect.
この意味は以下の通り。
b:= BankAccount new. ->BankAccountに new メッセージを送り、BankAccount クラスのインスタンスを生成する ->その返り値(インスタンス)を b に代入する ->"."はステートメントの終わりを示す。C言語の";" b:= BankAccount new. 全体を選択する。ラインの左端でクリックすれば良い。 メニューより "print it" する。ラインの後ろに a BankAccout が表示され、 これが ステートメントによって返された値であることが解る。
b inspect.
->オブジェクト b に inspect メッセージ を送る
このライン全体を選択し、”do it” する。この結果、インスタンスウィンドウが開かれる。
self をクリックすると、右側にそのオブジェクトの値 a BankAccout が表示される。
Instance Variable の balance の内容は nil になっている。nil は値が割り当てられていないことを示す、
Undefined Object のインスタンスである。何もしなければ、オブジェクトはnil で初期化される。
●メソッドの追加
Syatem Browser の第3 pane、メッセージカテゴリ ペインの”no messages" をクリックする。
コード pane に以下が表示される。
message selector and argument names
"comment stating purpose of message"
| temporary variable names |
statements
これはメソッドのテンプレートであり、意味は以下の通り。
message selector and argument names ->メッセージセレクタと引数名
"comment stating purpose of message" ->”コメント”
| temporary variable names | ->|使用する一時変数名|
statements ->ステートメント
これを以下の内容に変更する。”^”は returnで、balance の値を返すことを示す。ソースの表示は上向き矢印になる。
balance
"Return the balance"
^ balance
accept すると、イニシャル(名前)を聞いてくる。これはシステムが変更管理に使う。
balance の表示が ボールド体になる。 balance
initialize メソッドを追加する。
initialize
balance := 0.
Workspace で以下を do it する。
b initialize.
b inspect すると balance が 0 になっていることがわかる。
Morphic の素敵なところは、開かれているウィンドウがいつも自動更新されることだ。
inspector を balance の値を表示して開いたままで、コードを balance := 5 にし
Alt-s(accept)し Alt-d (do it) してみよう。
inspector で、balance の値は 5 に変わる。
Alt-p(print it) Alt-l(undo)もある。
deposit(預金) の追加
引数をもつメソッドである。
deposit: amount
balance := balance + amount.
Workspace で 以下を入力し、Alt-d する。
b deposit: 10.
withdraw(引き出し) の追加
withdraw: amount
amount > balance ifTrue: [^ self inform: 'sorry, not enough funds'].
balance := balance - amount.
これは、引き出し額 が預金残高より多ければ、[](ブロック)内の評価を行う。つまり、
「’残高不足です’ というメッセージを返す」
そうでなければ balance を amount 分減らす。
on the fly (即興的に)でこのクラスを変更してみよう。これは C や Javaでは
不可能なことだ。
System Browser で instance ボタンを押すとクラス定義が表示される。
history というインスタンス変数を追加しよう。
instanceVariableNames: 'balance history'
とし、Alt-s(accept)。今度は inspector を閉じて Workspace の上の b を選び
Alt-i(inspect)。history が表示される。
クラスを変更して accept すると、存在する全てのインスタンスは変更される。
ついでにいうと、"b"はどんな種類の変数かと聞かれても、答は無い。Workspace が
変数のバインディングの辞書(dictionary)を持っている。ただし、ローカル変数は
頭文字が小文字で始まり、グローバル変数は大文字で始まる。
Squeak では プログラミングのスタイルは ”late-binding programming" だ。
既に創ったものを変更することができる。Workspace がそれを行う場所だ。
実際のコーディングの際の試行錯誤は、System Browser ではなく、 Workspace
上で行われる。
history は balance のリストを保持することだ。そこで、受け付けたアイテムを
順番にリストとして保持するオブジェクトが必要だ。
initialize
balance := 0.
history := OrderedCollection new.
最初の行の最後に”."を追加するのを忘れないように。「そんな変数しりません」
などとエラーメッセージが出たら、これが原因。
OrderedCollection は 順序付きの無制限サイズの dynamic array。
Workspace で b initialize を選択し Alt-d(do it)。
inspector には history が OrderedCollection () と空のオブジェクトを
表示している。
次にこの空の OrderedCollection に値をいれる。balance が変わる時に呼ぶ
メソッドを創る。ここで history は balance の変更を保持することが出来る。
balance: newBalance
balance := newBalance.
history addLast: newBalance.
balance を更新し、history の最後に newBalance を追加している。
他の二つのメソッドも修正しよう。
deposit: amount
self balance: balance + amount.
withdraw: amount
amount > balance ifTrue: [^ self inform: 'sorry, not enough funds'].
self balance: balance - amount.
意味:
self balance: balance - amount.
(blance - amount) を引数にして、自分(インスタンス)の balance メソッドを呼び出す。
これらのメソッドは前と同じことをしているが、変数 balance: を直接操作するのでなく
メソッド balance: を使用している。
worekspace で 実行しよう。
b deposit:100.
inspector に105(5+100)が表示される。inspector で history を選択し、Workspace で
b depost:100. を選択し、繰り返し do it してみよう。history に 205、305と追加されて
いくのが表示される。履歴が順番に書き込まれている。
history をグラフィカルに見たいので、新しいメソッドを追加する。
historyMorph
| bars m |
bars := history collect: [:v | Morph new extent: 5@v].
m := AlignmentMorph newRow. (注1)
m addAllMorphs: bars.
^ m
history に collect: メッセージを送っている。collect: は(history)に送られたオブジェクトと
同じサイズの collection をつくる。[]で囲まれたブロックは history の各要素毎に評価される。
ブロックへは 値が変数"v"に渡される。"5@v"は座標で、X@Y を示す。extent: は Morph にサイズ
を伝える。
3行目では、bars を保持する AlignmentMorph を作成している。
4行目では、bars を subMorph の m に追加している。
5行目で、m を返している。
Workspace で以下を入力する。
b historyMorph.
b historyMorph openInWorld. (注2)
最初は、一行目だけを選択し、 print it する。 AlignmentMorph が返る。
2行目を実行する。下左端に青くぎざぎざの Bar Chat 風のものが見える。
#ソースをダウンロードしている場合は、Workspace より BankAccount execute. で実行可能。
#ただし、このMorph関係はいろいろ変更があるようで、表示結果はSqueakの版によってまちまちになる。参考と考えて下さい。
この Bar Chat は Morphic である。選択肢 Alt-click するとオブジェクトの周りに Morphic halo
(色のついたドットのセット)が表示される。黄色いハンドルでリサイズが出来るし、黒いハンドルで
外部へコピーを移動も出来る。ドットの上にカーソルを持っていけば、説明が出る。
回転させたのが、下の図。斜めの、グラフ状のものが Bar Chart。

bar chart Morphic は一つのオブジェクト(左上:回転している、右上:Alignment 設定が出来る)
Morphicの削除は、Alt-click して X で行える。
プロジェクトの終了の際は、全システム(image)を "save and quit" で保存する。
(注1)原文では、以下となっているが、Squeak3.0ではメソッドが無いとのエラーになるので、centering 以下を削除した。
m := AlignmentMorph newRow. centering: #bottomRight.
(注2)
Morph>>openInWorld
"Add this morph to the world. If in MVC, then provide a Morphic window for it."
self couldOpenInMorphic
ifTrue: [self openInWorld: self currentWorld]
ifFalse: [self openInMVC]
(以上)