{ import: Object } "Utility miscellaneous snipets. I hope these are included in the standard library." "----------------------------------------------------------------" "Bug fix" OrderedCollection makeRoomAtLast [ (self size == 0 and: [array size > 0]) ifTrue: [^self resetToBeginning]. (self size * 2 < array size) ifTrue: [^self shiftToBeginning]. array := (array new: self size + (array size max: 2)) replaceFrom: firstIndex to: lastIndex - 1 with: array startingAt: firstIndex; yourself. ] "----------------------------------------------------------------" File open: pathString do: aBlock [ | file | file := self open: pathString. aBlock value: file. file close ] File create: pathString do: aBlock [ | file | file := self create: pathString. aBlock value: file. file close ] "----------------------------------------------------------------" SmallInteger _value { _return (oop)((long)self >> 1); } SmallInteger value_: _i { _return (oop)((long)v__i << 1 | 1); } _assoc key [ ^key ] _vtable size [ ^SmallInteger value_: _tally ] _vtable at: index [ ^bindings at_: index _value ] _vector _size [ ^_size ] _vector at_: _index [ { int index= (long)v__index; int limit= (long)(self->v__size) >> 1; if ((index >= 0) && (index < limit)) _return(((oop *)self)[1 + index]); }. ^self primitiveFailed ] _vtable selectors [ | size sels | sels := Array new: (size := self size). 0 to: size - 1 do: [:i | sels at: i put: (self at: i) key]. ^sels ] nil allSelectors [ ^ IdentitySet new ] _vtable allSelectors [ ^ delegate allSelectors addAll: self selectors ] "----------------------------------------------------------------" Collection remove: anObject [ ^self remove: anObject ifAbsent: [self errorNotFound: anObject] ] Collection select: aBlock [ | newCollection | newCollection := self new. self do: [:each | (aBlock value: each) ifTrue: [newCollection add: each]]. ^newCollection ] "----------------------------------------------------------------" "for debugging" OrderedCollection _printOn: aStream [ super printOn: aStream. aStream cr. aStream nextPutAll: 'array: ', array printString; cr. aStream nextPutAll: 'firstIndex: ', firstIndex printString; cr. aStream nextPutAll: 'lastIndex: ', lastIndex printString; cr. ] SequenceableCollection findBinary: aBlock ifNone: exceptionBlock [ "Search for an element in the receiver using binary search. The argument aBlock is a one-element block returning 0 - if the element is the one searched for <0 - if the search should continue in the first half >0 - if the search should continue in the second half If no matching element is found, evaluate exceptionBlock." | index low high test item | low := 0. high := self size - 1. [index := high + low // 2. low > high] whileFalse:[ test := aBlock value: (item := self at: index). test = 0 ifTrue:[^item] ifFalse:[test > 0 ifTrue: [low := index + 1] ifFalse: [high := index - 1]]]. ^exceptionBlock value ] SequenceableCollection replaceFrom: first size: size with: aCollection [ ^ self replaceFrom: first to: first + size - 1 with: aCollection ] SequenceableCollection copyFrom: first size: size [ ^ self copyFrom: first to: first + size - 1 ] SequenceableCollection split: delimiter [ | lines start | "Splits the collection into a list of collections. Delimiters and empty elements are preserved. The behavior is different against Perl, Python, or Ruby." lines := WriteStream on: (Array new: 8). start := 0. self doWithIndex: [ :char :end | char = delimiter ifTrue: [ lines nextPut: (self copyFrom: start to: end). start := end + 1 ]]. start <= self size ifTrue: [ lines nextPut: (self copyFrom: start to: self size - 1)]. ^ lines contents ] " { import: TestCase } UtilityTest : TestCase () UtilityTest testSplit [ self assert: ('12345X12345' split: $X) size equals: 2. self assert: ('12345X12345X' split: $X) size equals: 3. self assert: ('12345X12345X' split: $X) second equals: '12345X'. self assert: ('12345X12345X' split: $X) third equals: ''. self assert: ('X' split: $X) size equals: 2. self assert: ('12345X12345X' asArray split: $X) size equals: 3. ] "