'From Squeak3.1alpha [latest update: #''Squeak3.1alpha'' of 28 February 2001 update 3923] on 11 April 2001 at 1:35:43 pm'! "Change Set: MIExtras-tk Date: 11 April 2001 Author: Ted Kaehler Characters respond correctly to clone (^ self). Move atRandom up to Collection, and define atRandom: in Set also. Streamline how MethodFinder finds constants for expressions of the type (data1 == 43) or (data1 < 52)."! !Character methodsFor: 'copying' stamp: 'tk 12/9/2000 11:46'! clone "Answer with the receiver, because Characters are unique."! ! !Collection methodsFor: 'accessing' stamp: 'tk 4/9/2001 15:26'! atRandom "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: Collection 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) "! ! !MessageSend methodsFor: 'printing' stamp: 'tk 10/24/2000 12:06'! printOn: strm super printOn: strm. strm space; nextPut: $(. receiver printOn: strm. strm space. selector printOn: strm. strm space. selector numArgs > 0 ifTrue: [arguments printOn: strm]. strm nextPut: $); space.! ! !MethodFinder methodsFor: 'search' stamp: 'tk 4/9/2001 18:01'! insertConstants "see if one of several known expressions will do it. C is the constant we discover here." "C data1+C data1*C data1//C (data1*C1 + C2) (data1 = C) (data1 ~= C) (data1 <= C) (data1 >= C) (data1 mod C)" thisData size >= 2 ifFalse: [^ self]. "need 2 examples" (thisData at: 1) size = 1 ifFalse: [^ self]. "only one arg, data1" self const ifTrue: [^ self]. self constUsingData1Value ifTrue: [^ self]. "(data1 ?? const), where const is one of the values of data1" " == ~~ ~= = <= >= " self allNumbers ifFalse: [^ self]. self constMod ifTrue: [^ self]. self constPlus ifTrue: [^ self]. self constMult ifTrue: [^ self]. self constDiv ifTrue: [^ self]. self constLinear ifTrue: [^ self]. ! ! !MethodFinder methodsFor: 'find a constant' stamp: 'tk 4/9/2001 17:59'! constUsingData1Value | const subTest got | "See if (data1 <= C) or (data1 >= C) is the answer" "quick test" ((answers at: 1) class superclass == Boolean) ifFalse: [^ false]. 2 to: answers size do: [:ii | ((answers at: ii) class superclass == Boolean) ifFalse: [^ false]]. thisData do: [:datums | const _ datums first. "use data as a constant!!" got _ (subTest _ MethodFinder new copy: self addArg: const) searchForOne isEmpty not. got ifTrue: [ "replace data2 with const in expressions" subTest expressions do: [:exp | expressions add: (exp copyReplaceAll: 'data2' with: const printString)]. selector addAll: subTest selectors. ^ true]]. ^ false! ! !Set methodsFor: 'accessing' stamp: 'tk 4/9/2001 15:21'! atRandom: aGenerator | ind | "Answer a random element of the receiver. Uses aGenerator which should be kept by the user in a variable and used every time. Use this instead of #atRandom for better uniformity of random numbers because only you use the generator. Causes an error if self has no elements." self emptyCheck. ind _ aGenerator nextInt: array size. [(array atWrap: (ind _ ind + 5)) == nil] whileTrue. ^ array atWrap: ind! ! Set removeSelector: #atRandom! SequenceableCollection removeSelector: #atRandom! MethodFinder removeSelector: #constLessThan!