関数タイルの作り方
とりあえず、RandomNumberTileをそのままコピーしてFunctionTileというクラスを作成。そしてFunctionTileから派生する形で他のタイルを作成しました。
というわけで以下にFunctionTileの中でRandomNumberTileからいじった内容を列挙(変更箇所をイタリックにしました)
クラス定義
TileMorph subclass: #FunctionTile instanceVariableNames: 'functionName thisFunction functionInString' classVariableNames: '' poolDictionaries: '' category: 'Morphic-Scripting Tiles'
※各変数は派生クラスにて定義。このクラスのインスタンスは生成しない。各変数の意味は以下のとおり
- functionName:表示に使う関数名
- functionInString:該当関数をコードに直したときの関数の文字列
- thisFunction:その関数のシンボル
FunctionTile >> initialize
initialize | t1 t2 | super initialize. self vResizing: #shrinkWrap. self typeColor: (ScriptingSystem colorForType: #Number). self addArrows. t1 := StringMorph contents: functionName translated font: ScriptingSystem fontForTiles. self addMorph: t1. t2 := UpdatingStringMorph contents: '180' font: ScriptingSystem fontForTiles. t2 target: self; getSelector: #literal; putSelector: #literal:. t2 position: t1 topRight. self addMorphBack: t2. literal := 180. self updateLiteralLabel. self makeAllTilesGreen
※関数の表示名を後で設定するようにした。無論このままだとfunctionNameが定義されていないのでおかしくなるが、これらは派生クラスで定義する。
FunctionTile >> numericValue
numericValue ^ super numericValue perform: thisFunction
※関数の値を返すメソッドと思われる。ただ、このメソッドはわざとエラーになるようなコードを挟んでも何も起きなかったのでどういうときにこのメソッドが使われているのか不明。
FunctionTile >> storeCodeOn:indent:
storeCodeOn: t1 indent: t2 t1 nextPut: $(; nextPutAll: literal printString; nextPutAll: ' '; nextPutAll: functionInString; nextPutAll: ')'
※実際の値の評価はこっちでやっている模様。ただ、numericValueと値の不整合を起こした場合、どういう状態になるのかは不明。
FunctionTile >> updateWordingToMathVocabulary
updateWordingToMatchVocabulary | t1 | t1 := submorphs detect: [:t2 | t2 class == StringMorph] ifNone: [^ self]. t1 contents: functionName translated
※何のメソッドかわからないがとりあえずatRandomとあったので該当部分を変更
その他
クラスメソッドのinitialize、registerInFlapsRegistryを削除
※部品等にそのクラスを格納するだけの機能だったので不要と判断
派生クラス
各派生クラスはinitializeだけをオーバーライドし、残りは定義しない。
例:SinTileのinitialize
initialize functionName := 'Sin'. functionInString := 'sin'. thisFunction := #sin. super initialize
※FunctionTileの各変数のみを定義し後は親クラスの初期化を行う。