Nicolas Cellier uploaded a new version of Collections to project The Inbox:
http://source.squeak.org/inbox/Collections-nice.767.mcz
==================== Summary ====================
Name: Collections-nice.767
Author: nice
Time: 8 November 2017, 12:46:38.73749 am
UUID: a3d23745-3d89-423e-9f25-a4d2dbf9864c
Ancestors: Collections-nice.766
Continue SortFunction refactoring
=============== Diff against Collections-nice.766 ===============
Item was changed:
SystemOrganization addCategory: #'Collections-Abstract'!
SystemOrganization addCategory: #'Collections-Arrayed'!
SystemOrganization addCategory: #'Collections-Cache'!
SystemOrganization addCategory: #'Collections-Exceptions'!
SystemOrganization addCategory: #'Collections-Heap'!
SystemOrganization addCategory: #'Collections-Sequenceable'!
+ SystemOrganization addCategory: #'Collections-SortFunctions'!
SystemOrganization addCategory: #'Collections-Stack'!
SystemOrganization addCategory: #'Collections-Streams'!
SystemOrganization addCategory: #'Collections-Strings'!
SystemOrganization addCategory: #'Collections-Support'!
SystemOrganization addCategory: #'Collections-Text'!
SystemOrganization addCategory: #'Collections-Unordered'!
SystemOrganization addCategory: #'Collections-Weak'!
Item was changed:
+ ----- Method: BlockClosure>>asSortFunction (in category '*Collections-SortFunctions-converting') -----
- ----- Method: BlockClosure>>asSortFunction (in category '*Collections-Support-sorting') -----
asSortFunction
+ "Return a SortFunction around the receiver. If the receiver is a 2 arg block, it is assumed it will do the collation directly itself, returning -1, 0, or 1. If the receiver is a one arg block, it will be evaluated for each a and b and of the sort input, and the result of sending <=> to those will be used"
+
+ self numArgs = 1 ifTrue: [^PropertySortFunction property: self].
+ self numArgs = 2 ifTrue: [^CollatorBlockFunction usingBlock: self].
+ self error: 'Cant be converted to sort function. It should has one or two args' !
- ^self ascending!
Item was changed:
+ ----- Method: BlockClosure>>ascending (in category '*Collections-SortFunctions-converting') -----
- ----- Method: BlockClosure>>ascending (in category '*Collections-Support-sorting') -----
ascending
"Return a SortFunction around the receiver. If the receiver is a 2 arg block, it is assumed it will do the collation directly itself, returning -1, 0, or 1. If the receiver is a one arg block, it will be evaluated for each a and b and of the sort input, and the result of sending <=> to those will be used."
+ ^self asSortFunction!
- self numArgs = 1 ifTrue: [^PropertySortFunction property: self].
- self numArgs = 2 ifTrue: [^CollatorBlockFunction new collator: self].
- self error: 'a block for sorting should have 1 or 2 parameters'!
Item was added:
+ ----- Method: BlockClosure>>collatedBy: (in category '*Collections-SortFunctions-converting') -----
+ collatedBy: aSortFunction
+ "Return a SortFunction around the receiver. If the receiver is a 2 arg block, it is assumed it will do the collation directly itself, returning -1, 0, or 1. If the receiver is a one arg block, it will be evaluated for each a and b and of the sort input, and the result of using aSortFunction on those will be used"
+
+ self numArgs = 1 ifTrue: [^PropertySortFunction property: self collatedWith: aSortFunction asSortFunction].
+ self error: 'Cant be converted to sort function. It should hava one arg' !
Item was changed:
+ ----- Method: BlockClosure>>descending (in category '*Collections-SortFunctions-converting') -----
- ----- Method: BlockClosure>>descending (in category '*Collections-Support-sorting') -----
descending
"Opposite direction as ascending."
+ ^self asSortFunction reversed!
- ^self ascending toggleDirection!
Item was removed:
- ----- Method: BlockClosure>>sortedWith: (in category '*Collections-Support-sorting') -----
- sortedWith: aSortFunction
- "Return a SortFunction around the receiver.
- The receiver is a one arg block.
- It will be evaluated for each a and b and of the sort input, and answer the result of collating those with aSortFunction."
-
- self numArgs = 1 ifTrue: [^PropertySortFunction property: self sortedWith: aSortFunction asSortFunction].
- self error: 'a block for sorting should have 1 or 2 parameters'!
Item was changed:
+ ComposedSortFunction subclass: #ChainedSortFunction
+ instanceVariableNames: 'nextFunction'
- SortFunction subclass: #ChainedSortFunction
- instanceVariableNames: 'next'
classVariableNames: ''
poolDictionaries: ''
+ category: 'Collections-SortFunctions'!
- category: 'Collections-Support'!
+ !ChainedSortFunction commentStamp: 'nice 11/7/2017 22:14' prior: 0!
+ I add to my parent the idea of a "next" function to use when two objects are equal by my primary sort function.
- !ChainedSortFunction commentStamp: 'nice 11/5/2017 22:35' prior: 0!
- I add to my parent the idea of a "next" function to use when two objects are equal by my particular collator.
Usage
SortFunctions can be chained together in primary, secondary, tertiary, etc order using the comma method. Consider a sequence of customer objects, where each customer object responds to the messages firstName, lastName, and age. If we want to sort them lastName first, then firstName, and finally oldest first, we would use an expression like:
customers sort: #lastName ascending, #firstName ascending, #age descending
As noted in my super's comment, unary symbols or single arg blocks can be used. One can omit the the ascending methods on arguments (not the receiver), it will default blocks or symbols to be ascending if none is specified. In other words, the above expression could be simplified slightly as
customers sort: #lastName ascending, #firstName, #age descending
(note the missing ascending on the #firstName argument)
Instance Variables
+ baseSortFunction <SortFunction> the primary SortFunction to collate given objects
+ next Function <SortFunction> the next SortFunction to evaluate in the event primary collation results are equal values!
- collator <SortFunction> the first SortFunction.
- next <SortFunction> the next SortFunction to evaluate in the event the first results in equal values.
-
- !
Item was added:
+ ----- Method: ChainedSortFunction class>>startWith:then: (in category 'instance creation') -----
+ startWith: aSortFunction then: nextSortFunction
+ ^self new
+ baseSortFunction: aSortFunction;
+ nextFunction: nextSortFunction!
Item was changed:
----- Method: ChainedSortFunction>>, (in category 'converting') -----
, aSortFunction
+ ^self class startWith: baseSortFunction then: nextFunction , aSortFunction!
- ^self copy next: next , aSortFunction!
Item was added:
+ ----- Method: ChainedSortFunction>>= (in category 'comparing') -----
+ = anObject
+ "Answer whether the receiver and anObject represent the same object."
+
+ self == anObject
+ ifTrue: [ ^ true ].
+ self class = anObject class
+ ifFalse: [ ^ false ].
+ ^ baseSortFunction = anObject baseSortFunction
+ and: [ nextFunction = anObject nextFunction ]!
Item was changed:
----- Method: ChainedSortFunction>>collate:with: (in category 'evaluating') -----
+ collate: anObject1 with: anObject2
+ "If the result of current function is 0, then pass on to the next function to work it out"
- collate: anObject with: bObject
- "Refinement of the parent behavior. If the result of my collator is 0, then pass on to the next variable to work it out."
| result |
+ result := baseSortFunction collate: anObject1 with: anObject2.
- result := (collator collate: anObject with: bObject).
^result isZero
+ ifTrue: [nextFunction collate: anObject1 with: anObject2.]
- ifTrue: [next collate: anObject with: bObject]
ifFalse: [result]!
Item was added:
+ ----- Method: ChainedSortFunction>>hash (in category 'comparing') -----
+ hash
+ "Answer an integer value that is related to the identity of the receiver."
+
+ ^ super hash + nextFunction hash!
Item was removed:
- ----- Method: ChainedSortFunction>>next: (in category 'initialize-release') -----
- next: anObject
-
- next := anObject!
Item was added:
+ ----- Method: ChainedSortFunction>>nextFunction (in category 'accessing') -----
+ nextFunction
+ ^nextFunction!
Item was added:
+ ----- Method: ChainedSortFunction>>nextFunction: (in category 'accessing') -----
+ nextFunction: aSortFunction
+ nextFunction := aSortFunction!
Item was changed:
SortFunction subclass: #CollatorBlockFunction
+ instanceVariableNames: 'collatorBlock'
- instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
+ category: 'Collections-SortFunctions'!
- category: 'Collections-Support'!
!CollatorBlockFunction commentStamp: 'nice 11/5/2017 22:57' prior: 0!
A CollatorBlockFunction is a special SortFunction using a dyadic block to collate objects.
Instance Variables
collator <Block> a dyadic block that must return a -1, 0, or 1.!
Item was added:
+ ----- Method: CollatorBlockFunction class>>usingBlock: (in category 'instance creation') -----
+ usingBlock: twoArgsBlock
+ ^self new
+ collatorBlock: twoArgsBlock!
Item was added:
+ ----- Method: CollatorBlockFunction>>= (in category 'comparing') -----
+ = anObject
+ "Answer whether the receiver and anObject represent the same object."
+
+ self == anObject
+ ifTrue: [ ^ true ].
+ self class = anObject class
+ ifFalse: [ ^ false ].
+ ^collatorBlock = anObject collatorBlock!
Item was changed:
----- Method: CollatorBlockFunction>>collate:with: (in category 'evaluating') -----
+ collate: anObject1 with: anObject2
+
+ ^collatorBlock value: anObject1 value: anObject2 !
- collate: value1 with: value2
- ^collator value: value1 value: value2!
Item was added:
+ ----- Method: CollatorBlockFunction>>collatorBlock (in category 'accessing') -----
+ collatorBlock
+ ^collatorBlock!
Item was added:
+ ----- Method: CollatorBlockFunction>>collatorBlock: (in category 'accessing') -----
+ collatorBlock: aBlock
+ collatorBlock := aBlock!
Item was added:
+ ----- Method: CollatorBlockFunction>>hash (in category 'comparing') -----
+ hash
+ "Answer an integer value that is related to the identity of the receiver."
+
+ ^ collatorBlock hash!
Item was added:
+ SortFunction subclass: #ComposedSortFunction
+ instanceVariableNames: 'baseSortFunction'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Collections-SortFunctions'!
+
+ !ComposedSortFunction commentStamp: 'nice 11/7/2017 22:13' prior: 0!
+ A ComposedSortFunction is an abstract class wrapping over another SortFunction for the sake of composition.
+
+ Subclasses have to define the composition behavior via collate:with: message.
+
+ Instances variables:
+ baseSortFunction <SortFunction> the wrapped sort function!
Item was added:
+ ----- Method: ComposedSortFunction class>>on: (in category 'instance creation') -----
+ on: aSortFunction
+ ^self new baseSortFunction: aSortFunction!
Item was added:
+ ----- Method: ComposedSortFunction>>= (in category 'comparing') -----
+ = aSortFunction
+ self == aSortFunction ifTrue: [ ^true ].
+ ^self class = aSortFunction class and: [ baseSortFunction = aSortFunction baseSortFunction ]!
Item was added:
+ ----- Method: ComposedSortFunction>>baseSortFunction (in category 'accessing') -----
+ baseSortFunction
+ ^baseSortFunction!
Item was added:
+ ----- Method: ComposedSortFunction>>baseSortFunction: (in category 'accessing') -----
+ baseSortFunction: aSortFunction
+ baseSortFunction := aSortFunction!
Item was added:
+ ----- Method: ComposedSortFunction>>hash (in category 'comparing') -----
+ hash
+ ^baseSortFunction hash hashMultiply!
Item was added:
+ ----- Method: ComposedSortFunction>>initialize (in category 'initailize-release') -----
+ initialize
+ super initialize.
+ baseSortFunction := self class default!
Item was changed:
SortFunction subclass: #DefaultSortFunction
instanceVariableNames: ''
+ classVariableNames: ''
- classVariableNames: 'UniqueInstance'
poolDictionaries: ''
+ category: 'Collections-SortFunctions'!
- category: 'Collections-Support'!
+ !DefaultSortFunction commentStamp: 'nice 11/7/2017 23:43' prior: 0!
- !DefaultSortFunction commentStamp: 'nice 11/5/2017 21:45' prior: 0!
A DefaultSortFunction is a collator using the default <=> operator.
It is known to work on String and Magnitude.
+ It is generally not usefull to create a new instance, and the recommended pattern is to use the single instance available by sending the message SortFunction default .
+
+ For other objects that don't understand threeWayCompareTo: it is necessary to use a custom SortFunction rather than the default one.
!
Item was added:
+ ----- Method: DefaultSortFunction class>>initialize (in category 'class initialization') -----
+ initialize
+ Default := self new!
Item was changed:
----- Method: DefaultSortFunction>>collate:with: (in category 'evaluating') -----
+ collate: anObject with: anotherObject
+ ^anObject <=> anotherObject!
- collate: value1 with: value2
- ^value1 <=> value2!
Item was removed:
- ----- Method: DefaultSortFunction>>initialize (in category 'initailize-release') -----
- initialize
- collator := #<=>!
Item was changed:
+ ComposedSortFunction subclass: #PropertySortFunction
- SortFunction subclass: #PropertySortFunction
instanceVariableNames: 'property'
classVariableNames: ''
poolDictionaries: ''
+ category: 'Collections-SortFunctions'!
- category: 'Collections-Support'!
!PropertySortFunction commentStamp: 'nice 11/5/2017 22:36' prior: 0!
A PropertySortFunction is a SortFunction for sorting by a specific property.
Instance Variables
collator <SortFunction> the SortFunction to be used for sorting the properties
property <Symbol | Block> a valuable returning the value of property for objects to be sorted!
Item was changed:
----- Method: PropertySortFunction class>>property: (in category 'instance creation') -----
+ property: selectorOrOneArgBlock
+ ^self new
+ property: selectorOrOneArgBlock!
- property: aValuable
- ^self new property: aValuable!
Item was added:
+ ----- Method: PropertySortFunction class>>property:collatedWith: (in category 'instance creation') -----
+ property: selectorOrOneArgBlock collatedWith: aSortFunction
+ ^self new
+ property: selectorOrOneArgBlock;
+ baseSortFunction: aSortFunction!
Item was removed:
- ----- Method: PropertySortFunction class>>property:sortedWith: (in category 'instance creation') -----
- property: aValuable sortedWith: aSortFunction
- ^self new property: aValuable; collator: aSortFunction!
Item was added:
+ ----- Method: PropertySortFunction>>= (in category 'comparing') -----
+ = anObject
+ "Answer whether the receiver and anObject represent the same object."
+
+ self == anObject
+ ifTrue: [ ^ true ].
+ self class = anObject class
+ ifFalse: [ ^ false ].
+ ^ baseSortFunction = anObject baseSortFunction
+ and: [ property = anObject property ]!
Item was changed:
----- Method: PropertySortFunction>>collate:with: (in category 'evaluating') -----
+ collate: anObject with: another
+ "Answer the collation order of anObject and another based on the property."
+ ^ baseSortFunction collate: (property value: anObject) with: (property value: another)!
- collate: value1 with: value2
- ^collator collate: (property value: value1) with: (property value: value2)!
Item was added:
+ ----- Method: PropertySortFunction>>hash (in category 'comparing') -----
+ hash
+ "Answer an integer value that is related to the identity of the receiver."
+
+ ^ super hash bitXor: property hash!
Item was added:
+ ----- Method: PropertySortFunction>>property (in category 'accessing') -----
+ property
+ ^ property!
Item was changed:
+ ----- Method: PropertySortFunction>>property: (in category 'accessing') -----
- ----- Method: PropertySortFunction>>property: (in category 'initailize-release') -----
property: aValuable
property := aValuable!
Item was changed:
----- Method: PropertySortFunction>>undefinedFirst (in category 'converting') -----
undefinedFirst
"apply on the property"
^self class
property: property
+ collatedWith: baseSortFunction undefinedFirst!
- sortedWith: (UndefinedSortFunction new collator: collator) undefinedFirst!
Item was changed:
----- Method: PropertySortFunction>>undefinedLast (in category 'converting') -----
undefinedLast
"apply on the property"
^self class
property: property
+ collatedWith: baseSortFunction undefinedLast!
- sortedWith: (UndefinedSortFunction new collator: collator) undefinedLast!
Item was changed:
+ ComposedSortFunction subclass: #ReverseSortFunction
- SortFunction subclass: #ReverseSortFunction
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
+ category: 'Collections-SortFunctions'!
- category: 'Collections-Support'!
+ !ReverseSortFunction commentStamp: 'nice 11/6/2017 21:54' prior: 0!
+ A ReverseSortFunction wraps over another SortFunction so as to sort in reverse order.!
- !ReverseSortFunction commentStamp: 'nice 11/5/2017 22:40' prior: 0!
- A ReverseSortFunction is reversing the order of original sortFunction
-
- Instance Variables
- collator <SortFunction> the original SortFunction.
- !
Item was changed:
----- Method: ReverseSortFunction>>collate:with: (in category 'evaluating') -----
+ collate: anObject with: another
+ ^(baseSortFunction collate: anObject with: another) negated!
- collate: value1 with: value2
- ^(collator collate: value1 with: value2) negated!
Item was added:
+ ----- Method: ReverseSortFunction>>reversed (in category 'converting') -----
+ reversed
+ ^baseSortFunction!
Item was changed:
----- Method: ReverseSortFunction>>undefinedFirst (in category 'converting') -----
undefinedFirst
"apply on the original"
+ ^baseSortFunction undefinedLast reversed!
- ^collator undefinedFirst toggleDirection!
Item was changed:
----- Method: ReverseSortFunction>>undefinedLast (in category 'converting') -----
undefinedLast
"apply on the original"
+ ^baseSortFunction undefinedFirst reversed!
- ^collator undefinedLast toggleDirection!
Item was changed:
Object subclass: #SortFunction
+ instanceVariableNames: ''
+ classVariableNames: 'Default'
- instanceVariableNames: 'collator'
- classVariableNames: ''
poolDictionaries: ''
+ category: 'Collections-SortFunctions'!
- category: 'Collections-Support'!
!SortFunction commentStamp: 'nice 11/5/2017 22:52' prior: 0!
I am intended to be used in place of two arg sort blocks.
Usage
In the following example, an ascending SortFunction is created based on the result of the #first message send to each object.
#(#(1 2) #(2 3) #(0 0)) sorted: #first ascending.
To sort by the #last element, but descending, the following would be used:
#(#(1 2) #(2 3) #(0 0)) sorted: #last descending.
One can use blocks as well. The following sorts in descending order, the sub elements based on the sum of their values.
| sumBlock |
sumBlock := [:sequence | sequence inject: 0 into: [:sum :each | sum + each]].
#(#(1 2) #(2 3) #(0 0)) sorted: sumBlock descending.
One can even use 2 arg blocks, for those cases where the function isn't expressible with objects that respond to < and =. The only catch, is that such a function has to return not true and false, but instead a collation order, values of -1 (for before), 0 (the same) or 1 (to follow). For example:
| oddBlock |
oddBlock :=
[:a :b |
a odd = b odd ifTrue: [0] ifFalse: [a odd ifTrue: [-1] ifFalse: [1]]].
#(1 5 1 3 2 7 9 4 6) asSortedCollection: oddBlock descending
Instance Variables
collator <SortFunction> This is the object responsible for collating objetcs, generally a SortFunction.
!
Item was added:
+ ----- Method: SortFunction class>>default (in category 'accessing') -----
+ default
+ ^Default!
Item was changed:
----- Method: SortFunction>>, (in category 'converting') -----
, aSortFunction
"Return a new SortFunction which is the concatenation of aSortFunction to me, I will be the primary sort, but if I compare equal, I will defer to the argument."
+ ^ChainedSortFunction startWith: self then: aSortFunction asSortFunction!
- ^(ChainedSortFunction new)
- collator: self;
- next: aSortFunction asSortFunction!
Item was removed:
- ----- Method: SortFunction>>collator: (in category 'initailize-release') -----
- collator: aSortFunction
- "Used by subclasses for composition."
-
- collator := aSortFunction!
Item was removed:
- ----- Method: SortFunction>>initialize (in category 'initailize-release') -----
- initialize
- "set the default collator"
-
- collator := DefaultSortFunction new!
Item was added:
+ ----- Method: SortFunction>>reversed (in category 'converting') -----
+ reversed
+ "Return new sort function with reverse sort order."
+
+ ^ReverseSortFunction on: self!
Item was removed:
- ----- Method: SortFunction>>toggleDirection (in category 'converting') -----
- toggleDirection
- ^ReverseSortFunction new collator: self!
Item was changed:
----- Method: SortFunction>>undefinedFirst (in category 'converting') -----
undefinedFirst
+ "Return a new SortFunction that sort all the nil first, an non nil with myself."
+ ^(UndefinedSortFunction on: self) undefinedFirst!
- ^(UndefinedSortFunction new collator: self) undefinedFirst!
Item was changed:
----- Method: SortFunction>>undefinedLast (in category 'converting') -----
undefinedLast
+ "Return a new SortFunction that sort all the nil last, an non nil with myself."
+ ^(UndefinedSortFunction on: self) undefinedLast!
- ^(UndefinedSortFunction new collator: self) undefinedLast!
Item was changed:
+ ----- Method: Symbol>>asSortFunction (in category '*Collections-SortFunctions-converting') -----
- ----- Method: Symbol>>asSortFunction (in category 'sorting') -----
asSortFunction
+ "Return a SortFunction around the receiver, where the receiver will be used as a unary message to send to both a and b during sorting, and then the result of said send will be collated in ascending order using the <=> method."
+ "#('abc' 'de' 'fghi') sorted: #size ascending >>> #('de' 'abc' 'fghi')"
+ ^PropertySortFunction property: self!
- ^self ascending!
Item was changed:
+ ----- Method: Symbol>>ascending (in category '*Collections-SortFunctions-converting') -----
- ----- Method: Symbol>>ascending (in category 'sorting') -----
ascending
"Return a SortFunction around the receiver, where the receiver will be used as a unary message to send to both a and b during sorting, and then the result of said send will be collated in ascending order using the <=> method."
+ "#('abc' 'de' 'fghi') sorted: #size ascending >>> #('de' 'abc' 'fghi')"
- "Example: #('abc' 'de' 'fghi') sorted: #size asscending"
+ ^self asSortFunction !
- ^PropertySortFunction property: self!
Item was added:
+ ----- Method: Symbol>>collatedBy: (in category '*Collections-SortFunctions-converting') -----
+ collatedBy: aSortFunction
+ "Return a SortFunction around the receiver, where the receiver will be used as a unary message to send to both a and b during sorting, and then the result of said send will be collated iusing aSortFunction."
+ "#('abc' 'de' 'fghi') sorted: (#size collatedWith: [:e|e bitAnd: 1]) , #size >>> #( 'de' 'fghi' 'abc')"
+
+ ^PropertySortFunction property: self collatedWith: aSortFunction asSortFunction!
Item was changed:
+ ----- Method: Symbol>>descending (in category '*Collections-SortFunctions-converting') -----
- ----- Method: Symbol>>descending (in category 'sorting') -----
descending
"Return a SortFunction around the receiver, where the receiver will be used as a unary message to send to both a and b during sorting, and then the result of said send will be collated in descending order using the <=> method."
+ "#('abc' 'de' 'fghi') sorted: #size ascending >>> #('fghi' 'abc' 'de')"
- "Example: #('abc' 'de' 'fghi') sorted: #size descending"
+ ^self asSortFunction reversed!
- ^(PropertySortFunction property: self) toggleDirection!
Item was removed:
- ----- Method: Symbol>>sortedWith: (in category 'sorting') -----
- sortedWith: aSortFunction
- "Return a SortFunction around the receiver, where the receiver will be used as a unary message to send to both a and b during sorting, and then the result of said send will be collated in descending order using the aSortFunction."
- "Example: #('abc' 'de' 'fghi') sorted: (#size collatedBy: #<=> asSortFunction)"
-
- ^PropertySortFunction property: self sortedWith: aSortFunction asSortFunction!
Item was changed:
+ ComposedSortFunction subclass: #UndefinedSortFunction
- SortFunction subclass: #UndefinedSortFunction
instanceVariableNames: 'direction'
classVariableNames: ''
poolDictionaries: ''
+ category: 'Collections-SortFunctions'!
- category: 'Collections-Support'!
+ !UndefinedSortFunction commentStamp: 'nice 11/7/2017 22:16' prior: 0!
+ An UndefinedSortFunction is a specialization usefull for sorting undefined objects (nil), either first or last according to direction.
+ The non nil objects are sorted according to the baseSortFunction defined in superclass.
- !UndefinedSortFunction commentStamp: 'nice 11/5/2017 23:18' prior: 0!
- An UndefinedSortFunction is a specialization of SortFunction for sorting UndefinedObject either first or last.
+ instance variables:
+ direction <Integer> -1 for sorting nil first, 1 for sorting nil last!
- Instance Variables
- collator <SortFunction> the SortFunction to be used for non nil values
- direction: <Integer> -1 if nil is sorted first, 1 if sorted last
- !
Item was added:
+ ----- Method: UndefinedSortFunction>>= (in category 'comparing') -----
+ = anObject
+ "Answer whether the receiver and anObject represent the same object."
+
+ self == anObject
+ ifTrue: [ ^ true ].
+ self class = anObject class
+ ifFalse: [ ^ false ].
+ ^ baseSortFunction = anObject baseSortFunction
+ and: [ direction = anObject direction ]!
Item was changed:
----- Method: UndefinedSortFunction>>collate:with: (in category 'evaluating') -----
+ collate: anObject with: another
+ "Answer the collation order of anObject and another, with nil first or last according to direction"
+ anObject ifNil: [^another ifNil: [0] ifNotNil: [direction]].
+ another ifNil: [^direction negated].
+ ^baseSortFunction collate: anObject with: another!
- collate: value1 with: value2
- value1 ifNil: [^value2 ifNil: [0] ifNotNil: [direction]].
- value2 ifNil: [^direction negated].
- ^collator collate: value1 with: value2!
Item was added:
+ ----- Method: UndefinedSortFunction>>direction (in category 'accessing') -----
+ direction
+ ^direction!
Item was added:
+ ----- Method: UndefinedSortFunction>>hash (in category 'comparing') -----
+ hash
+ "Answer an integer value that is related to the identity of the receiver."
+
+ ^ super hash bitXor: direction hash!
Just reposting the message
http://lists.squeakfoundation.org/pipermail/squeak-dev/2017-September/19530…
below so that it gets a proper subject line.
Note: SharedQueue and SharedQueue2 are both in the image.
SharedQueue2 was included into Squeak version 3.9 by MarcusDenker
(10-07-2005) for further testing.
Lex Spoon notes one year later that no problems have come to light. We
should start migrating to this. All it requires is replacing
SharedQueue by SharedQueue2.
Then two years later (12-17-2008) Keith_Hodges proposes a migration script
"fix begin"
Installer mantis bug: 1375 fix: 'M1375-SharedQueue2Enable.1.cs'.
WorldState initialize.
EventSensor initialize.
"fix end"
We need somebody to have a look at this script
'M1375-SharedQueue2Enable.1.cs' if it is still good to do the task.
BTW Pharo does not have two implementations of SharedQueue.
HH.
SharedQueue
I provide synchronized communication of arbitrary objects between
Processes. An object is sent by sending the message nextPut: and
received by sending the message next. If no object has been sent when
a next message is sent, the Process requesting the object will be
suspended until one is sent.
SharedQueue2
An implementation of a shared queue based on class Monitor. Clients
may may place items on the queue using nextPut: or remove them using
methods like next or nextOrNil. Items are removed in first-in
first-out (FIFO) order. It is safe for multiple threads to access the
same shared queue, which is why this is a "shared" queue.
[monitor] is used to synchronize access from multiple threads.
[items] is an ordered collection holding the items that are in the
queue. New items are added at the end, and old items are removed
from the beginning.
All methods must hold the monitor while they run.
Levente Uzonyi
<leves(a)caesar.elte.hu> Wed, Sep 20, 2017 at 6:44 PM
Reply-To: The general-purpose Squeak developers list
<squeak-dev(a)lists.squeakfoundation.org>
To: The general-purpose Squeak developers list
<squeak-dev(a)lists.squeakfoundation.org>
On Wed, 20 Sep 2017, H. Hirzel wrote:
On 9/20/17, Levente Uzonyi <leves(a)caesar.elte.hu> wrote:
These methods were there to make it possible to migrate from SharedQueue
to SharedQueue2 in a live system.
Could you please give some more background information about this migration?
http://bugs.squeak.org/view.php?id=1375
That migration has not happened yet,
Is there a reason not to do it after 5 years?
The mantis issue above has a few potential reasons.
Another one may be that now there are other potential shared queue
implementations to replace SharedQueue.
tim Rowledge uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-tpr.1116.mcz
==================== Summary ====================
Name: Kernel-tpr.1116
Author: tpr
Time: 6 November 2017, 10:08:58.237421 pm
UUID: f921b28f-0d4a-4ed9-9a28-b5d7d6db279a
Ancestors: Kernel-tpr.1115
Untangle a mis-thought deprecation and sort out windowTitle/labelString until a thorough job might be done
=============== Diff against Kernel-tpr.1115 ===============
Item was added:
+ ----- Method: Model>>labelString (in category 'toolbuilder') -----
+ labelString
+ "We'd love to sunset this in favour of #windowTitle but there are so many places that would need changing that it really seems more trouble than could possibly be warranted"
+ ^self class name!
Item was changed:
----- Method: Model>>windowTitle (in category 'toolbuilder') -----
windowTitle
+ "We'd rather use windowTitle but labelString is deeply embedded; see its comment"
+ ^self labelString!
- ^self class name!
tim Rowledge uploaded a new version of 51Deprecated to project The Trunk:
http://source.squeak.org/trunk/51Deprecated-tpr.50.mcz
==================== Summary ====================
Name: 51Deprecated-tpr.50
Author: tpr
Time: 6 November 2017, 10:07:31.953541 pm
UUID: afd8e74a-907f-44e6-97c4-b053f743c826
Ancestors: 51Deprecated-tpr.49
Argh, no. Deprecarte the deprecation
=============== Diff against 51Deprecated-tpr.49 ===============
Item was removed:
- ----- Method: StringHolder>>labelString (in category '*51Deprecated') -----
- labelString
- ^self windowTitle!
Does anyone have a problem with StringHolder>buildWindowWith* being promoted to Model and the now redundant Font[Chooser|Importer]Tool versions getting removed? It seems to me a reasonably general pair of methods with applicability to other Model related classes, like for example, the new file chooser & saver dialogues I’m preparing.
tim
--
tim Rowledge; tim(a)rowledge.org; http://www.rowledge.org/tim
Strange OpCodes: CM: Circulate Memory
tim Rowledge uploaded a new version of PreferenceBrowser to project The Trunk:
http://source.squeak.org/trunk/PreferenceBrowser-tpr.81.mcz
==================== Summary ====================
Name: PreferenceBrowser-tpr.81
Author: tpr
Time: 6 November 2017, 3:05:26.99732 pm
UUID: 5fa48827-2a97-4871-9f65-d7dfc0f634bf
Ancestors: PreferenceBrowser-eem.80
Moved the performance test to SystemNavigation
=============== Diff against PreferenceBrowser-eem.80 ===============
Item was changed:
----- Method: PreferenceWizardMorph>>hasLowPerformance (in category 'testing') -----
hasLowPerformance
"If the wizard is started on a machine with low performance, the wizard will change some settings automatically on startup."
+ ^ Smalltalk isLowerPerformance!
- ^ (Smalltalk platformSubtype beginsWith: 'arm') "Raspberry PI"
- or: [Smalltalk platformName = 'Web'] "SqueakJS"!
tim Rowledge uploaded a new version of MorphicTests to project The Trunk:
http://source.squeak.org/trunk/MorphicTests-tpr.42.mcz
==================== Summary ====================
Name: MorphicTests-tpr.42
Author: tpr
Time: 6 November 2017, 3:04:08.351007 pm
UUID: 570171ed-9cc8-468c-812e-45dacc21f405
Ancestors: MorphicTests-mt.41
Derive default timeout from the default timeout... no, really
=============== Diff against MorphicTests-mt.41 ===============
Item was changed:
----- Method: MorphicUIManagerTest>>defaultTimeout (in category 'accessing') -----
defaultTimeout
+ ^ super defaultTimeout * 10 "seconds"!
- ^ 60 "seconds"!
tim Rowledge uploaded a new version of Tests to project The Trunk:
http://source.squeak.org/trunk/Tests-tpr.386.mcz
==================== Summary ====================
Name: Tests-tpr.386
Author: tpr
Time: 6 November 2017, 3:02:55.613898 pm
UUID: 0c28c2ef-1d3f-4987-95d4-e8685e878e03
Ancestors: Tests-ul.385
Derive default timeout from the default timeout... no, really
=============== Diff against Tests-ul.385 ===============
Item was changed:
----- Method: LangEnvBugs>>defaultTimeout (in category 'as yet unclassified') -----
defaultTimeout
+ ^ super defaultTimeout * 10 "seconds"!
- ^ 60!
Item was changed:
----- Method: MCMczInstallerTest>>defaultTimeout (in category 'as yet unclassified') -----
defaultTimeout
+ ^ super defaultTimeout * 10 "seconds"!
- ^ 60!
tim Rowledge uploaded a new version of SUnit to project The Trunk:
http://source.squeak.org/trunk/SUnit-tpr.110.mcz
==================== Summary ====================
Name: SUnit-tpr.110
Author: tpr
Time: 6 November 2017, 3:01:43.268905 pm
UUID: 0754924f-c223-4120-a86a-2973ccaac087
Ancestors: SUnit-eem.109
Make the default timeout for TestCases depend on the system performance check
=============== Diff against SUnit-eem.109 ===============
Item was changed:
----- Method: TestCase>>defaultTimeout (in category 'accessing') -----
defaultTimeout
"Answer the default timeout to use for tests in this test case.
The timeout is a value in seconds."
+ ^Smalltalk isLowerPerformance ifTrue:[ 25] ifFalse: [5] "seconds"!
- ^5 "seconds"!