コレクションの実装
Posted feedbacks - Nested
Flatten HiddenSqueak Smalltalkでは、Collectionクラスを継承し、#add: #do: #remove:ifAbsent: #atRandom: を再定義することで、要求されるインターフェイスを満たす新たなコレクションクラスを設けることが可能です。
Bagクラスの定義が参考になるでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | Collection subclass: #MyCollection
instanceVariableNames: 'contents'
MyCollection >> add: element
^contents add: element
MyCollection >> do: aBlock
contents do: [:each | aBlock value: each]
MyCollection >> remove: element ifAbsent: aBlock
^contents remove: element ifAbsent: [aBlock value]
MyCollection >> atRandom: aGenerator
^contents atRandom: aGenerator
MyCollection >> setContents: newContents
contents := newContents
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "
MyCollection class >> new
^self new: 1
MyCollection class >> new: numElements
^super new setContents: (OrderedCollection new: numElements); yourself
MyCollection class >> newFrom: aCollection
^self withAll: aCollection
MyCollection class >> example
| myCollection |
myCollection := MyCollection newFrom: #(4 3 2 1). "=> a MyCollection(4 3 2 1) "
myCollection collect: [:each | each * 2]. "=> a MyCollection(8 6 4 2) "
myCollection select: [:each | each even]. "=> a MyCollection(4 2) "
myCollection max. "=> 4 "
myCollection * 2. "=> a MyCollection(8 6 4 2) "
myCollection atRandom "=> 3 "
|
書き忘れましたが、新しく定義したコレクションについて collection + 2 のような処理ができるのは当然として、Smalltalk の場合、さらに、2 + collection のように交換した場合も評価可能になります。これって、今回の拡張とは全然関係のない 2(が属するクラス SmallInteger)の #+ というメソッドをコールする…というオブジェクト指向の仕組みのことを考えるとちょっと不思議で面白い機能だと思いませんか?
拡張に対するこのような柔軟性は、有名な「ダブルディスパッチ」という仕組みにより実現されています。
1 2 3 4 | | myCollection |
myCollection := MyCollection newFrom: (1 to: 3). "=> a MyCollection(1 2 3) "
myCollection + 2. "=> a MyCollection(3 4 5) "
2 + myCollection. "=> a MyCollection(3 4 5) "
|




柿 #9728() [ Ruby ] Rating-4/4=-1.00
コレクションフレームワークに則ってコレクションクラスを実装して下さい.
具体的にどのようなコレクションを実装しても構いませんが,コレクションフレームワークで用意された基本的なメソッドは一通り呼べるようにして下さい. foreach系の構文があれば,それでも使えるとよいです.
例えば,Rubyであれば以下のようなコードで(mapを直接定義することなく)要素を列挙できる必要があるでしょう.
Rating-4/4=-1.00-0+
[ reply ]