Nicolas Cellier uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.589.mcz
==================== Summary ====================
Name: Collections-ul.589
Author: ul
Time: 17 December 2014, 3:31:06.906 pm
UUID: 3f079add-7154-43c9-a265-bd59cb4cbcb8
Ancestors: Collections-bf.588
- Deprecated Collection class >> #randomForPicking.
- Replaced all accesses to RandomForPicking with ThreadSafeRandom value.
- WeakKeyDictionary >> associationsDo: ignores associations with GC'd keys. This affects all enumerator methods, and makes overriding #keysDo: unnecessary.
- Added a new method SequenceableCollection #>> groupsDo:, which works like #groupsOf:atATimeDo:, but uses the block's argument count as the group size.
Depends on Kernel-ul.891
=============== Diff against Collections-bf.588 ===============
Item was changed:
----- Method: Collection class>>randomForPicking (in category 'private') -----
randomForPicking
+
+ self deprecated: 'Use ThreadSafeRandom value instead. It''s not thread-safe to use this instance without the unaccessible MutexForPicking semaphore.'.
^ RandomForPicking!
Item was changed:
----- Method: Collection>>atRandom (in category 'accessing') -----
atRandom
+ "Answer a random element of the receiver. Uses the process-local random number generator. Causes an error if self has no elements."
- "Answer a random element of the receiver. Uses a shared random
- number generator owned by class Collection. If you use this a lot,
- define your own instance of Random and use #atRandom:. Causes
- an error if self has no elements."
+ ^self atRandom: ThreadSafeRandom value
- ^ self class mutexForPicking critical: [
- self atRandom: self class randomForPicking ]
"Examples:
#('one' 'or' 'the' 'other') atRandom
(1 to: 10) atRandom
'Just pick one of these letters at random' atRandom
#(3 7 4 9 21) asSet atRandom (just to show it also works for Sets)
"!
Item was added:
+ ----- Method: SequenceableCollection>>groupsDo: (in category 'enumerating') -----
+ groupsDo: aBlock
+ "Evaluate aBlock with my elements taken n at a time, where n is the number of arguments of aBlock. Ignore any leftovers at the end."
+
+ | index argumentArray numArgs endIndex |
+ numArgs := aBlock numArgs.
+ numArgs
+ caseOf: {
+ [ 0 ] -> [ ^self error: 'At least one block argument expected.' ].
+ [ 1 ] -> [ ^self do: aBlock ].
+ [ 2 ] -> [ ^self pairsDo: aBlock ] }
+ otherwise: [].
+ argumentArray := Array new: numArgs.
+ index := 1.
+ endIndex := self size - numArgs + 1.
+ [ index <= endIndex ] whileTrue: [
+ argumentArray
+ replaceFrom: 1
+ to: numArgs
+ with: self
+ startingAt: index.
+ aBlock valueWithArguments: argumentArray.
+ index := index + numArgs ].!
Item was changed:
----- Method: SequenceableCollection>>shuffle (in category 'shuffling') -----
shuffle
+ ^self shuffleBy: ThreadSafeRandom value!
- ^self shuffleBy: Collection randomForPicking!
Item was changed:
----- Method: SequenceableCollection>>shuffled (in category 'copying') -----
shuffled
+ ^ self shuffledBy: ThreadSafeRandom value
- ^ self shuffledBy: Collection randomForPicking
"Examples:
($A to: $Z) shuffled
"!
Item was added:
+ ----- Method: WeakKeyDictionary>>associationsDo: (in category 'enumerating') -----
+ associationsDo: aBlock
+ "Evaluate aBlock for each of the receiver's elements (key/value
+ associations)."
+
+ tally = 0 ifTrue: [ ^self].
+ 1 to: array size do: [ :index |
+ (array at: index) ifNotNil: [ :association |
+ association key ifNotNil: [ :key | "Don't let the key go away."
+ aBlock value: association ] ] ]!
Item was removed:
- ----- Method: WeakKeyDictionary>>keysDo: (in category 'enumerating') -----
- keysDo: aBlock
- "Evaluate aBlock for each of the receiver's keys."
-
- self associationsDo: [ :association |
- association key ifNotNil: [ :key | "Don't let the key go away"
- aBlock value: key ] ].!
Nicolas Cellier uploaded a new version of GraphicsTests to project The Trunk:
http://source.squeak.org/trunk/GraphicsTests-nice.52.mcz
==================== Summary ====================
Name: GraphicsTests-nice.52
Author: nice
Time: 12 February 2019, 11:59:21.898092 pm
UUID: a952a9e4-3d82-45e8-b538-ff74679e9722
Ancestors: GraphicsTests-mt.51
Don't rely on Interval = Array.
=============== Diff against GraphicsTests-mt.51 ===============
Item was changed:
----- Method: CharacterScannerTest>>testBreakAnywhereWhenFirstCharDoesNotFit (in category 'testing') -----
testBreakAnywhereWhenFirstCharDoesNotFit
| p text cbs |
text := ((String new: 2 withAll: $m) , (String space) , (String new: 2 withAll: $m)) asText.
p := NewParagraph new.
p
compose: text
style: style
from: 1
in: (0 @ 0 corner: mWidth-1 @ (style lineGrid * 7)).
self assert: p lines size equals: text size + 1 description: 'Each character is on a new line, past end also'.
+ self assert: (p lines collect: #first) equals: (1 to: text size + 1) asArray description: 'Each character is on a new line'.
- self assert: (p lines collect: #first) equals: (1 to: text size + 1) description: 'Each character is on a new line'.
cbs := (1 to: text size + 1) collect: [:i | p characterBlockForIndex: i].
self assert: (cbs collect: #left as: Set) size = 1 description: 'Selecting before each character align on left'
!
Nicolas Cellier uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-nice.820.mcz
==================== Summary ====================
Name: Collections-nice.820
Author: nice
Time: 12 February 2019, 11:56:35.262017 pm
UUID: bb383133-067c-4133-987b-c481a7de69c7
Ancestors: Collections-ul.819, Collections-cbc.813
Definitively abandon SequenceableCollection equality tests based on equal species.
Old behaviour can still be obtained thru hasEqualElements: but the default is to not try to support such trans-class equality feature because it is much too complex.
Particularly Interval are no more equal to Arrays with same sequence. We can thus optimize hash a bit more and fix the old bugs of equa objects with different hashes. Merge Collections-cbc.813 for this and rehashAll in postscript.
There are not so many classes concerned by this change, mainly RunArray, Interval and LinkedList:
Collection withAllSubclasses select: [:e | [e basicNew species ~= e] on: Error do: [false]]
-> an OrderedCollection(WeakRegistry LinkedList Interval ByteCharacterSet CharacterSetComplement LazyCharacterSet WideCharacterSet ShortRunArray Semaphore Mutex TextLineInterval WeakArray Monitor MCVersionName ByteSymbol WideSymbol)
We will have to change the tests that rely on such equality.
=============== Diff against Collections-ul.819 ===============
Item was changed:
----- Method: FloatArray>>= (in category 'comparing') -----
= aFloatArray
- | length |
<primitive: 'primitiveEqual' module: 'FloatArrayPlugin'>
+ ^super = aFloatArray!
- aFloatArray class = self class ifFalse: [^ false].
- length := self size.
- length = aFloatArray size ifFalse: [^ false].
- 1 to: self size do: [:i | (self at: i)
- = (aFloatArray at: i) ifFalse: [^ false]].
- ^ true!
Item was changed:
----- Method: Interval>>= (in category 'comparing') -----
= anObject
-
^ self == anObject
+ or: [anObject isInterval
+ ifFalse: [super = anObject]
+ ifTrue:
+ [start = anObject first
+ and: [step = anObject increment
+ and: [self last = anObject last]]]]!
- ifTrue: [true]
- ifFalse: [anObject isInterval
- ifTrue: [start = anObject first
- and: [step = anObject increment
- and: [self last = anObject last]]]
- ifFalse: [super = anObject]]!
Item was changed:
----- Method: Interval>>hash (in category 'comparing') -----
hash
"Hash is reimplemented because = is implemented."
+ ^((start hash hashMultiply bitXor: self last hash) hashMultiply
+ bitXor: self size)!
-
- ^(((start hash bitShift: 2)
- bitOr: stop hash)
- bitShift: 1)
- bitOr: self size!
Item was changed:
----- Method: RunArray>>= (in category 'comparing') -----
= anObject
+ self == anObject ifTrue: [^ true].
- "Test if all my elements are equal to those of anObject"
-
^anObject class == self class
+ and:
- ifTrue: "Faster test between two RunArrays"
[(runs hasEqualElements: anObject runs)
+ and: [values hasEqualElements: anObject values]]!
- and: [values hasEqualElements: anObject values]]
- ifFalse:
- [anObject isCollection and: [self hasEqualElements: anObject]]!
Item was changed:
----- Method: SequenceableCollection>>= (in category 'comparing') -----
= otherCollection
"Answer true if the receiver is equivalent to the otherCollection.
+ First test for identity, then rule out different class and sizes of
- First test for identity, then rule out different species and sizes of
collections. As a last resort, examine each element of the receiver
and the otherCollection."
self == otherCollection ifTrue: [^ true].
+ self class == otherCollection class ifFalse: [^ false].
- self species == otherCollection species ifFalse: [^ false].
^ self hasEqualElements: otherCollection!
Item was changed:
----- Method: Symbol>>= (in category 'comparing') -----
= aSymbol
"Compare the receiver and aSymbol."
self == aSymbol ifTrue: [^ true].
+ aSymbol isSymbol ifTrue: [^ false].
- self class == aSymbol class ifTrue: [^ false].
"Use String comparison otherwise"
^ super = aSymbol!
Item was changed:
+ (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable.
+ HashedCollection rehashAll.'!
- (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable'!
Nicolas Cellier uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-cbc.813.mcz
==================== Summary ====================
Name: Collections-cbc.813
Author: cbc
Time: 20 November 2018, 11:28:59.501218 am
UUID: 78c08e62-a381-284a-b476-6e638d99f91d
Ancestors: Collections-cbc.812
Altered Interval>>hash to increase entropy
=============== Diff against Collections-cbc.812 ===============
Item was changed:
----- Method: Interval>>hash (in category 'comparing') -----
hash
"Hash is reimplemented because = is implemented."
+ ^((start hash hashMultiply bitXor: self last hash) hashMultiply
+ bitXor: self size)!
-
- ^(((start hash bitShift: 2)
- bitOr: self last hash)
- bitShift: 1)
- bitOr: self size!
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.1213.mcz
==================== Summary ====================
Name: Kernel-nice.1213
Author: nice
Time: 8 February 2019, 11:24:45.054968 pm
UUID: d7a472c9-49dd-4b1d-b73a-13b9c7c8d4c5
Ancestors: Kernel-tonyg.1212
Provide a logarithm in base 2: log2.
This (x log2) has an additional property that (x log: 2) has not: it is exact for exact powers of 2.
While implementing LogarithmicInterval, I recently wanted to use log: 2, and this was getting as bad as in Python. See https://stackoverflow.com/questions/931995/inaccurate-logarithm-in-python/5…
I don't know if this feature is really worth it, but whether it ends up integrated or not, at least it demonstrates how easy it is to patch Squeak.
=============== Diff against Kernel-tonyg.1212 ===============
Item was added:
+ ----- Method: Float>>log2 (in category 'mathematical functions') -----
+ log2
+ "Answer the base 2 logarithm of the receiver.
+ Arrange to answer exact result in case of exact power of 2."
+
+ ^ self significand ln / Ln2 + self exponent!
Item was added:
+ ----- Method: Fraction>>log2 (in category 'mathematical functions') -----
+ log2
+ "This function is defined because super log might overflow."
+ | res |
+ self <= 0 ifTrue: [DomainError signal: 'log2 is only defined for x > 0'].
+ "Test self < 1 before converting to float in order to avoid precision loss due to gradual underflow."
+ numerator < denominator ifTrue: [^self reciprocal log2 negated].
+ res := super log2.
+ res isFinite ifTrue: [^res].
+ ^numerator log2 - denominator log2!
Item was added:
+ ----- Method: Integer>>log2 (in category 'mathematical functions') -----
+ log2
+ self > 0 ifTrue: [^super log2].
+ ^DomainError signal: 'log2 is only defined for x > 0'!
Item was added:
+ ----- Method: LargeNegativeInteger>>log2 (in category 'mathematical functions') -----
+ log2
+ ^DomainError signal: 'log2 is only defined for x > 0'!
Item was added:
+ ----- Method: LargePositiveInteger>>log2 (in category 'mathematical functions') -----
+ log2
+ "This function is defined because super log2 might overflow."
+ | res h |
+ res := super log2.
+ res isFinite ifTrue: [^res].
+ h := self highBit.
+ ^h + (self / (1 << h)) asFloat log2!
Item was added:
+ ----- Method: Number>>log2 (in category 'mathematical functions') -----
+ log2
+ "Answer the base-2 log of the receiver."
+
+ ^self asFloat log2!
Item was changed:
----- Method: Number>>log: (in category 'mathematical functions') -----
log: aNumber
"Answer the log base aNumber of the receiver."
+ aNumber = 2 ifTrue: [^self log2].
^self ln / aNumber ln!
Item was added:
+ ----- Method: ScaledDecimal>>log2 (in category 'mathematical functions') -----
+ log2
+ "Unlike super, avoid Float overflow/underflow"
+
+ ^self asFraction log2!
Patrick Rein uploaded a new version of Help-Squeak-Project to project The Trunk:
http://source.squeak.org/trunk/Help-Squeak-Project-pre.66.mcz
==================== Summary ====================
Name: Help-Squeak-Project-pre.66
Author: pre
Time: 7 February 2019, 8:50:02.069431 pm
UUID: 230ce268-a872-4b95-98d8-2a4d6cdadf28
Ancestors: Help-Squeak-Project-pre.65
Removes an example method which did not work in a stable way and improved the presentation of the example list.
=============== Diff against Help-Squeak-Project-pre.65 ===============
Item was changed:
----- Method: SqueakMessageCategoriesHelp class>>addCategoryTopicsTo: (in category 'private') -----
addCategoryTopicsTo: aTopic
self selectors sorted do: [:selector | | helpContents examples |
examples := (self new perform: selector).
examples := examples isCollection ifTrue: [examples] ifFalse: [#()].
helpContents := (self commentsAt: selector) first asText,
String crlf asText , String crlf asText ,
('Examples:' asText allBold; yourself) ,
String crlf asText ,
+ ((examples collect: [:m | m reference]) joinSeparatedBy: ', ' , String crlf) asText.
- ((examples collect: [:m | m reference]) joinSeparatedBy: ', ') asText.
aTopic addSubtopic: ((HelpTopic
title: (self organization categoryOfElement: selector)
icon: (HelpIcons iconNamed: #pageIcon)
contents: helpContents)
priority: 999;
yourself)]!
Item was changed:
----- Method: SqueakMessageCategoriesHelp>>failures (in category 'failures') -----
failures
"This category is most often used with TestCase classes. It contains any methods denoting failures for this TestCase"
+ ^ {"There is no stable example method for this"}!
- ^ {RectangleTest>>#expectedFailures}!
Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.819.mcz
==================== Summary ====================
Name: Collections-ul.819
Author: ul
Time: 3 February 2019, 6:41:04.151586 pm
UUID: 73993c05-fb6d-497a-9d99-2087eff4e1a4
Ancestors: Collections-pre.818
- merge sort tweaks
=============== Diff against Collections-pre.818 ===============
Item was changed:
----- Method: ArrayedCollection>>mergeFirst:middle:last:into:by: (in category 'sorting') -----
mergeFirst: first middle: middle last: last into: dst by: aBlock
"Private. Merge the sorted ranges [first..middle] and [middle+1..last]
of the receiver into the range [first..last] of dst."
| i1 i2 val1 val2 out |
i1 := first.
i2 := middle + 1.
val1 := self at: i1.
val2 := self at: i2.
out := first - 1. "will be pre-incremented"
"select 'lower' half of the elements based on comparator"
+ [ (i1 <= middle) and: [ i2 <= last ] ] whileTrue: [
- [ (i1 <= middle) and: [ i2 <= last ] ] whileTrue: [
(aBlock
ifNil: [ val1 <= val2 ]
ifNotNil: [ aBlock value: val1 value: val2 ])
ifTrue: [
dst at: (out := out + 1) put: val1.
val1 := self at: (i1 := i1 + 1)]
ifFalse: [
dst at: (out := out + 1) put: val2.
+ val2 := self atWrap: (i2 := i2 + 1) ] ].
- (i2 := i2 + 1) <= last ifTrue: [
- val2 := self at: i2 ] ] ].
"copy the remaining elements"
i1 <= middle
ifTrue: [dst replaceFrom: out + 1 to: last with: self startingAt: i1]
ifFalse: [dst replaceFrom: out + 1 to: last with: self startingAt: i2]!
Item was changed:
----- Method: ArrayedCollection>>mergeSortFrom:to:by: (in category 'sorting') -----
mergeSortFrom: startIndex to: stopIndex by: aBlock
"Sort the given range of indices using the mergesort algorithm.
Mergesort is a worst-case O(N log N) sorting algorithm that usually
does only half as many comparisons as heapsort or quicksort."
"Details: recursively split the range to be sorted into two halves,
mergesort each half, then merge the two halves together. An extra
copy of the data is used as temporary storage and successive merge
phases copy data back and forth between the receiver and this copy.
The recursion is set up so that the final merge is performed into the
receiver, resulting in the receiver being completely sorted."
| size |
(size := self size) <= 1 ifTrue: [^ self]. "nothing to do"
startIndex = stopIndex ifTrue: [^ self].
1 <= startIndex ifFalse: [ self errorSubscriptBounds: startIndex ].
stopIndex <= size ifFalse: [ self errorSubscriptBounds: stopIndex ].
startIndex < stopIndex ifFalse: [ self errorSubscriptBounds: startIndex ].
+ self shallowCopy
- self
mergeSortFrom: startIndex
to: stopIndex
+ into: self
- src: self shallowCopy
- dst: self
by: aBlock!
Item was added:
+ ----- Method: ArrayedCollection>>mergeSortFrom:to:into:by: (in category 'sorting') -----
+ mergeSortFrom: firstIndex to: lastIndex into: destination by: aBlock
+ "Private. Split the range to be sorted in half, sort each half, and
+ merge the two half-ranges into destination."
+
+ | n firstObject lastObject |
+ "Precondition: firstIndex <= lastIndex, self and destination contain the same elements between firstIndex and lastIndex inclusively but not necessarily in the same order"
+ (n := lastIndex - firstIndex) <= 1 ifTrue: [ "Handle 1 and 2 sized ranges directly."
+ n = 0 ifTrue: [ ^self ].
+ firstObject := self at: firstIndex.
+ lastObject := self at: lastIndex.
+ (aBlock
+ ifNil: [ firstObject <= lastObject ]
+ ifNotNil: [ aBlock value: firstObject value: lastObject ])
+ ifFalse: [
+ destination
+ at: lastIndex put: firstObject;
+ at: firstIndex put: lastObject ]
+ ifTrue: [
+ destination
+ at: lastIndex put: lastObject;
+ at: firstIndex put: firstObject ].
+ ^self ].
+ n := firstIndex + lastIndex // 2.
+ destination mergeSortFrom: firstIndex to: n into: self by: aBlock.
+ destination mergeSortFrom: n + 1 to: lastIndex into: self by: aBlock.
+ self mergeFirst: firstIndex middle: n last: lastIndex into: destination by: aBlock!
Item was removed:
- ----- Method: ArrayedCollection>>mergeSortFrom:to:src:dst:by: (in category 'sorting') -----
- mergeSortFrom: first to: last src: src dst: dst by: aBlock
- "Private. Split the range to be sorted in half, sort each half, and
- merge the two half-ranges into dst."
-
- | middle |
- first = last ifTrue: [^ self].
- middle := (first + last) // 2.
- self mergeSortFrom: first to: middle src: dst dst: src by: aBlock.
- self mergeSortFrom: middle + 1 to: last src: dst dst: src by: aBlock.
- src mergeFirst: first middle: middle last: last into: dst by: aBlock!