ブロックとValueHolderのダックタイピング

いきなりだが、とりあえずクラスを作ってみる。
定義するのはwindowSpecとコンボボックスのaspectとchoiseの三つ。

windowSpec
    ^#(#{UI.FullSpec} 
        #window: 
        #(#{UI.WindowSpec} 
            #label: 'Unlabeled Canvas' 
            #min: #(#{Core.Point} 20 20 ) 
            #max: #(#{Core.Point} 0 0 ) 
            #bounds: #(#{Graphics.Rectangle} 640 400 829 463 ) ) 
        #component: 
        #(#{UI.SpecCollection} 
            #collection: #(
                #(#{UI.ComboBoxSpec} 
                    #layout: #(#{Graphics.Rectangle} 10 6 178 33 ) 
                    #name: #ComboBox1 
                    #colors: 
                    #(#{UI.LookPreferences} 
                        #setSelectionForegroundColor: #(#{Graphics.ColorValue} #black ) 
                        #setSelectionBackgroundColor: #(#{Graphics.ColorValue} #white ) ) 
                    #model: #aCombo 
                    #type: #timestamp 
                    #formatString: 'yyyy/m/d h:mm:ss A/P' 
                    #comboList: #aComboList ) ) ) )

aCombo
    ^aCombo isNil
        ifTrue:
            [aCombo := nil asValue]
        ifFalse:
            [aCombo]

aComboList
    ^(List with: Timestamp now) asValue

では画面をオープンして、コンボをクリックしてみよう。
何度クリックし直しても、プルダウンするのは画面オープン時の時刻だろう。

次に、aComboListを次のように書き換える。
aComboList
    ^[List with: Timestamp now]

そして画面を開き直し、コンボをクリック。
今度はクリックした時刻へと刻々と変化するのがわかる。

さて、ここで重要なのは、aComboListがValueHolderを返しても、ブロックを返しても、
何も問題なく動作したということだ。
どちらもvalueというメソッドを理解し、同じように中身を評価して返し、そして
コンボのプルダウンはvalueの返り値を表示しているからだ。

これこそがダックタイピングだ・・・なんといいかげんなという感じだが、valueという共通する
メソッドがあらかじめ定義されているおかげで、ComboBoxButtonXXXXクラスをいじることなく、
表層の画面クラスでリストを毎回評価するか、一回評価するか使い分けることができるというわけだ。

ちなみに、おそらくシンコムの開発者たちが意図していなかった使用法だと思う。
なぜなら、プルダウンウィンドウの高さを決めるためだけにself list sizeとかやっているからだ。
ブロックに対してこれをやると、ブロックの中身を何度も評価して非常にパフォーマンスが悪い。
結局・・・ブロックで実装するためにはComboBoxButtonViewクラスにリスト数を保持するための
インスタンス変数を追加することになるんだな・・・

  • からオシャレで清楚な上質な女の子が素敵な夜をお届け致します(*´ェ`*)★ http://sns.fgn.asia/ -- 飛鳥 (2012-08-22 00:47:43)
名前:
コメント:
-

タグ:

+ タグ編集
  • タグ:
最終更新:2012年08月22日 00:47
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。