LoginSignup
5
2

More than 5 years have passed since last update.

Smalltalk Smalltalk クラス作成編

Last updated at Posted at 2014-12-06

Smalltalk クラス作成編

既存クラス等の紹介をしてきましたが、今回はSystem Browserを使って自分でクラスを作成をしてみます。また作成したクラスのテストケースを作成し、ユニットテストをしてみます。

作成するクラスを考える

今回はOrderedDictionaryというクラスを作りましょう。Dictionaryは順序は保存しないクラスですが、順序を持ったDictionaryを作成しましょう。(RubyのOrderedHashを作るということです)。ちなみに、Smalltalkコミュニティのメンバーが作成したSmallTalk R4.1 http://smalltalk.smalltalk-users.jp/ にはHashというクラスで実装されております。

[追記]後日知ったのですがPharoには、OrderedIdentityDictionaryといったクラスも存在しておりました。OrderedDictionaryと異なりvaluesの結果は順序が保たれてはいないようです。

OrderedDictionaryの要件

OrderedDictionaryの実行結果を以下に記述しますので、実現するクラスを作成していきます。

Sample
"workspace"
| dict |
dict := OrderedDictionary new.
dict at: #x put: 1.
dict at: #z put: 3.
dict at: #y put: 2.
dict values. "print it ==> #(1 3 2)"
dict do:[:v | Transcript cr; show: v] . 
dict removeKey:#x.
dict removeKey:#y.
dict removeKey:#z.

System Browserの確認

Smalltalk開発環境入門編にてSystem Browserを少し説明しましたが、ここでSystem Browserの見方を紹介します。System Browserは左から、クラスカテゴリ、クラス、メソッドカテゴリ、メソッドの順に表示され、それぞれを定義します。下の一番大きい領域はコードペインと呼び、実際のコードを記述します。
Objective-Cを使ったことがある方は、Smalltalkのクラス定義の方法を知るとヘッダーファイルとメソッドファイルの存在理由がわかると思います。

classBrowser.jpg

パッケージ(クラスカテゴリ)の追加

まずはパッケージ、クラスカテゴリの追加をします。クラスカテゴリはクラスをまとめるために使います。クラスカテゴリの追加は、クラスカテゴリにて右クリック[Add Package]をクリックして、カテゴリ名を入力します。

addpackage.png

今回ははAdvent-Collectionsとします。

advent-collections.png

クラスの定義

続いては、クラスを定義していきましょう。クラス定義は、コードペインに記述します。クラスカテゴリ追加時点では、以下のようなクラス定義のテンプレートが表示されていると思います。

Object subclass: #NameOfSubclass
    instanceVariableNames: ''
    classVariableNames: ''
    category: 'Advent-Collections'

このテンプレートを変更してクラスを作成していきます。Smalltalkのクラスは必ずスーパークラスを持ちます。

テンプレートの説明
クラス定義 スーパークラス名 subclass: #クラス名
    instanceVariableNames: 'インスタンス変数名1 インスタンス変数名2'   
    classVariableNames: 'クラス変数名1 クラス変数名2'
    category: 'クラスカテゴリ' 

OrderedDictionaryを作成します。コードペインを以下のように記述します。今回はObjectクラスを継承したクラスにします。インスタンス変数は、キーの順序を保管するkeysとキーと値を保管するcontentsを用意します。

OrderedDictionary
Object subclass: #OrderedDictionary
    instanceVariableNames: 'keys contents'
    classVariableNames: ''
    category: 'Advent-Collections'

メソッドカテゴリの追加

続いてインスタンス変数を整理するためのメソッドカテゴリを作成します。メソッドカテゴリの名前は、Smalltalkの他のクラスを参考にしながら作成するとよいでしょう。例えば、初期化をするinitializeはinitializationカテゴリに所属することが多いです。インスタンスメソッドinitializeはクラスにnewを送ってオブジェクト生成する際に自動起動するメソッドです。System Browserでクラス名を選択した状態でメソッドカテゴリ領域で右クリックで追加できます。

methodCategory.png

インスタンスメソッドの定義

インスタンスメソッドはSystem Browserでメソッドカテゴリ名を選択した状態でコードペインにて記述します。以下のコードを記述します。

OrderedDictionary>>initialize
initialize
    keys := OrderedCollection new.
    contents := Dictionary new.

記述したらコードを保存します。保存方法はコードペイン上で右クリックをして[Accept]をクリックします(ショートカット Macならcommand + s, WindowsならALt + s)。初めてソースコードを保存する場合は、名前を確認されますので入力しましょう。

accept.png

その他のメソッドも実装します。

accesingカテゴリ

OrderedDictionary>>at
at: key
    ^ contents at: key
OrderedDictionary>>at
at: key put: value
    contents at: key put: value.
    (keys includes:key) ifFalse:[
        keys add: key. ].
    ^ value.
OrderedDictionary>>keys
keys
    ^ keys
OrderedDictionary>>size
size
    ^ keys size
OrderedDictionary>>values
values
    | out |
    out := WriteStream on: (Array new: keys size).
    keys do:[:v | 
        out nextPut: (contents at:v)].
    ^ out contents
OrderedDictionary>>removeKey
removeKey: key
    keys remove: key.
    contents removeKey: key.

OrderedDictionary.jpeg

emulatingカテゴリ

OrderedDictionary>>do
do: aBlock
    keys do:[:v | aBlock value:v ].

動作確認

Worksapceで動作確認をしてみましょう。

自動テストを作成する

作成したOrderedDictionaryですが、機能としては少なく改良の余地がありそうです。改良するたびに毎回テストするのは非常に辛い作業です。そこでSUnitを使って自動テストを行うようにします。実はJavaのJUnitはSUnitを元に開発されていたりします。

SUnitを使ったテストの記述方法は色々とありますが、今回は一番単純なものを紹介します。テストするメソッドを選択して、右クリック。[Generate test and jump]をクリック。

sunit.png

作成されると以下のクラスとメソッドが作成されます。
OrderedDictionaryTest>>#testAt.jpeg

あとはテスト内容を記述します。

SmalltalkOrderedDictionaryTest>>testAt
testAt
    | dict |
    dict := OrderedDictionary new.
    dict at: #x put: 1.
    dict at: #z put: 3.
    dict at: #y put: 2.
    self assertCollection: (dict keys) equals:(Array with:#x with:#z with:#y) asOrderedCollection. 

自動テストの実行

テストを実行するには、テストメソッドの左のボタンをクリックします。

testrun.png

テストが成功するとボタンがグリーンになります。

green.png

またはTest Runnerからも実行できます。

testrunner.png

参考

自由自在 Squeakプログラミング PDF版
http://swikis.ddo.jp/squeak/13

今日から使おうSmalltalk
http://www.slideshare.net/newapplesho/smalltalk-32627289

Pharo by Example
http://www.pharobyexample.org/

SmallTalk R4.1
http://smalltalk.smalltalk-users.jp/

Smalltalk開発環境入門編
http://qiita.com/newapplesho/items/4a90c0771e15506c8484

テスト駆動開発入門, Kent Beck, ピアソン

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2