Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.1120.mcz
==================== Summary ====================
Name: Kernel-nice.1120
Author: nice
Time: 13 November 2017, 10:24:19.857289 pm
UUID: 24277641-be23-40ea-85ef-1db0d48f63d3
Ancestors: Kernel-mt.1119
1) Use // in Fraction>>gcd:, rather than / will was invoking the same gcd: computation 4 times!
2) Enhance the Fraction comment
The Fraction comment SHALL tell about the expected class invariants.
At least, it should help answering questions like:
https://stackoverflow.com/questions/46942103/squeak-smalltalk-why-sometimes…https://stackoverflow.com/questions/46905203/squeak-smalltalk-why-reduction…
While at it, also tell why 3 isFraction answers true, and 3.0 asFraction -> an Integer, not a Fraction.
VW (st80?) has chosen better #isRational and #asRational messages for making things a bit more clear, but without a Rational superclass, it's not that obvious...
=============== Diff against Kernel-mt.1119 ===============
Item was changed:
Number subclass: #Fraction
instanceVariableNames: 'numerator denominator'
classVariableNames: ''
poolDictionaries: ''
category: 'Kernel-Numbers'!
+ !Fraction commentStamp: 'nice 11/13/2017 22:09' prior: 0!
+ Fraction provides methods for dealing with fractions like 1/3 as a ratio of two integers (as apposed to a decimal representation 0.33333...).
- !Fraction commentStamp: '<historical>' prior: 0!
- Fraction provides methods for dealing with fractions like 1/3 as fractions (not as 0.33333...). All public arithmetic operations answer reduced fractions (see examples).
+ instance variables:
+ numerator <Integer> the number appearing before the fraction bar (above)
+ denominator <Integer> the number appearing after the fraction bar (below)
+
+ A Fraction is generally created by sending the message / to an Integer, like in
- instance variables: 'numerator denominator '
+ 1 / 3
- Examples: (note the parentheses required to get the right answers in Smalltalk and Squeak):
+ Alternatively, it is possible to create a new instance of Fraction by sending #numerator:denominator: to the class.
+ In this later case, it is then user responsibility to ensure that it conforms to the following invariants:
+
+ - the denominator shall allways be positive.
+ A negative Fraction shall have a negative numerator, never a negative denominator.
+ Example: 1 / -3 will return -1/3
+ - the denominator shall allways be greater than 1.
+ A Fraction with denominator 1 shall be reduced to its numerator (an Integer).
+ Example 3 / 1 will answer 3 (the Integer) not 3/1
+ - the numerator and denominator shall never have common multiples.
+ Common multiples shall allways be simplified until (numerator gcd: denominator) = 1.
+ Example 8 / 6 will answer 4 / 3, because both 8=2*4 and 6=2*3 are both divisible by 2.
+
+ A Fraction non conforming to above invariants could be the cause of undefined behavior and unexpected results.
+ If unsure, it is advised to send the message #reduced to the freshly created instance so as to obtain a conforming Fraction, or an Integer.
+
+ Note that Fraction and Integer represent together the set of Rational numbers:
+ - Integer is a subset of rational (those which are whole numbers)
+ - Fraction is used for representing the complementary subset of rational (those which are not whole numbers)
+
+ There could have been a Rational superclass to both Integer and Fraction, and a message #isRational for testing if a Number is a Rational, as well as a message #asRational for converting a Number to a Rational.
+ But this level of indirection is not strictly necessary: instead, the notion of Rational and Fraction are collapsed in Squeak, and Integer are considered as a sort of special Fraction with unitary denominator.
+ Thus #isFraction is the testing message, to which every Integer will answer true, since considered as a sort of Fraction.
+ And #asFraction is the conversion message, that may answer an instance of Fraction of Integer, depending if the corresponding rational number is whole or not.
+
+ All public arithmetic operations will answer reduced fractions.
+ Examples:
+
(2/3) + (2/3)
+ (2/3) + (1/2) "case showing reduction to common denominator"
+ (2/3) + (4/3) "case where result is reduced to an Integer"
+ (2/3) raisedToInteger: 5 "fractions also can be exponentiated"
- (2/3) + (1/2) "answers shows the reduced fraction"
- (2/3) raisedToInteger: 5 "fractions also can have exponents"
!
Item was changed:
----- Method: Fraction>>gcd: (in category 'arithmetic') -----
gcd: aFraction
| d |
d := denominator gcd: aFraction denominator.
+ ^(numerator *(aFraction denominator//d) gcd: aFraction numerator*(denominator//d)) / (denominator//d*aFraction denominator)!
- ^(numerator *(aFraction denominator/d) gcd: aFraction numerator*(denominator/d)) / (denominator/d*aFraction denominator)!
Eliot Miranda uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-eem.767.mcz
==================== Summary ====================
Name: Collections-eem.767
Author: eem
Time: 14 November 2017, 11:29:19.620473 am
UUID: 9705b40c-d81d-4667-b9eb-fbfccbe2e955
Ancestors: Collections-bp.766
Make the Transcript's characterLimit a preference.
=============== Diff against Collections-bp.766 ===============
Item was changed:
WriteStream subclass: #TranscriptStream
instanceVariableNames: 'lastChar'
+ classVariableNames: 'AccessSema CharacterLimit ForceUpdate RedirectToStdOut'
- classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut'
poolDictionaries: ''
category: 'Collections-Streams'!
!TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0!
This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.!
Item was added:
+ ----- Method: TranscriptStream class>>characterLimit (in category 'preferences') -----
+ characterLimit
+ <preference: 'Maximum number of characters in a transcript'
+ categoryList: #(printing morphic debug)
+ description: 'When the number of characters in a transcript exceeds this limit, characters at the start of the text are discarded.'
+ type: #Number>
+ ^CharacterLimit ifNil: [20000]!
Item was changed:
----- Method: TranscriptStream>>characterLimit (in category 'accessing') -----
characterLimit
"Tell the views how much to retain on screen"
+ ^self class characterLimit!
- ^ 20000!
Eliot Miranda uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-eem.975.mcz
==================== Summary ====================
Name: System-eem.975
Author: eem
Time: 14 November 2017, 11:22:51.118839 am
UUID: d8e00134-ca31-43fb-8558-8bf9a15c7aba
Ancestors: System-tpr.974
Add the ability to set a pragma preference stored in a class or global variable by analysing the getter, obviating the need for a setter.
Improve the class comment for PragmaPreference and mention this feature.
=============== Diff against System-tpr.974 ===============
Item was changed:
Preference subclass: #PragmaPreference
instanceVariableNames: 'provider getter setter'
classVariableNames: ''
poolDictionaries: ''
category: 'System-Preferences'!
+ !PragmaPreference commentStamp: 'eem 11/14/2017 11:20' prior: 0!
+ Differs from superclass by redirecting all queries to a preference provider that defines its preference via a class-side preference method marked with a pragma. For example, evaluate
+ self systemNavigation browseAllCallsOn: #preference:categoryList:description:type:
+
+ Each preference method getter can be accompanied by a setter that assigns to the preference whose value the getter answers. If the getter is of the form
+ ^SomeGlobalOrClassVar ifNil: [...]
+ then the framework is smart enough to figure out the SomeGlobalOrClassVar from the getter and no setter method is required.!
- !PragmaPreference commentStamp: 'ar 3/9/2009 21:27' prior: 0!
- Differs from superclass by redirecting all queries to preference provider.!
Item was added:
+ ----- Method: PragmaPreference>>attemptToSetValueFromGetter: (in category 'value') -----
+ attemptToSetValueFromGetter: aValue
+ "Attempt to set the value of the preference from the getter method, answering if the attempt was successful.
+ Do so by seeing if the method is of the form
+ ^ClassVar ifNil: [...]
+ by analysing its bytecode, and if so, extracting the class (or global) var and setting its value."
+ | getterMethod getterBytecodes getterBytecodeNames
+ constant comparison branchTuple distance followingpc
+ classVar |
+ getterMethod := provider class compiledMethodAt: getter ifAbsent: [^false].
+ getterBytecodes := getterMethod abstractBytecodeMessagesAndPCs.
+ getterBytecodeNames := getterBytecodes collect: [:tuple| tuple first selector].
+ ((getterBytecodeNames beginsWith: #(pushLiteralVariable: doDup #pushConstant: send:super:numArgs: jump:if:))
+ and: [getterBytecodeNames last == #methodReturnTop
+ and: [(constant := getterBytecodes third first) arguments first == nil
+ and: [(comparison := getterBytecodes fourth first) arguments first == #==
+ and: [branchTuple := getterBytecodes fifth.
+ followingpc := getterBytecodes sixth last.
+ distance := branchTuple first arguments first.
+ "i.e. does the branch jump to the return?"
+ distance + followingpc = getterBytecodes last second]]]]) ifFalse:
+ [^false].
+ classVar := getterBytecodes first first arguments first.
+ classVar value: aValue.
+ ^true!
Item was changed:
----- Method: PragmaPreference>>rawValue: (in category 'value') -----
rawValue: aValue
"set the value as indicated, with no side effects"
+ [provider perform: setter with: aValue]
+ on: MessageNotUnderstood
+ do: [:ex|
+ (self attemptToSetValueFromGetter: aValue) ifFalse:
+ [ex pass]]!
- provider perform: setter with: aValue!
Eliot Miranda uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-eem.1121.mcz
==================== Summary ====================
Name: Kernel-eem.1121
Author: eem
Time: 14 November 2017, 11:10:07.464042 am
UUID: 98880dc0-3ab4-4b8d-90ee-c5aab215e3b4
Ancestors: Kernel-eem.1120
fix comment typo
=============== Diff against Kernel-eem.1120 ===============
Item was changed:
----- Method: CompiledCode>>abstractBytecodeMessagesAndPCs (in category 'scanning') -----
abstractBytecodeMessagesAndPCs
+ "Answer the receiver's sequence of abstract bytecodes as a sequence of tuples of bytecode message and pc."
- "Answer the receiver's sequence of abstract bytecodes as a sequence of tuples of bytecode mnessage and pc."
"(CompiledCode >> #abstractBytecodeMessagesAndPCs) abstractBytecodeMessagesAndPCs"
| msgs initial endpc pc scanner |
scanner := InstructionStream new method: self pc: (initial := self initialPC).
msgs := OrderedCollection new: (endpc := self endPC) - initial.
[(pc := scanner pc) <= endpc] whileTrue:
[[scanner interpretNextInstructionFor: nil]
on: MessageNotUnderstood
do: [:ex| msgs addLast: { ex message. pc }]].
^msgs!
David T. Lewis uploaded a new version of ST80Tests to project The Trunk:
http://source.squeak.org/trunk/ST80Tests-dtl.5.mcz
==================== Summary ====================
Name: ST80Tests-dtl.5
Author: dtl
Time: 13 November 2017, 9:26:52.125552 pm
UUID: 5bcbeaa0-c4f2-46c0-b555-d0312fff6f91
Ancestors: ST80Tests-pre.4
Remove unnecessary references to global world.
Do not test nil World for project type, instead use Project current isMVC
=============== Diff against ST80Tests-pre.4 ===============
Item was changed:
----- Method: MVCToolBuilderTests>>testWindowCloseAction (in category 'tests-not applicable') -----
testWindowCloseAction
"This can only work if we're actually run in MVC"
+ Project current isMVC ifTrue: [super testWindowCloseAction]!
- World isNil ifTrue: [super testWindowCloseAction]!
David T. Lewis uploaded a new version of ST80 to project The Trunk:
http://source.squeak.org/trunk/ST80-dtl.231.mcz
==================== Summary ====================
Name: ST80-dtl.231
Author: dtl
Time: 13 November 2017, 9:24:36.982919 pm
UUID: 6b7b06d8-8c1e-477a-8ac1-89f6377bab8a
Ancestors: ST80-tpr.230
Remove unnecessary references to global world.
Do not test nil World for project type, instead use Project current isMVC
=============== Diff against ST80-tpr.230 ===============
Item was changed:
----- Method: MVCProject>>storeSegment (in category 'file in/out') -----
storeSegment
"Store my project out on the disk as an ImageSegment. Keep the outPointers in memory. Name it <project name>.seg. *** Caller must be holding (Project alInstances) to keep subprojects from going out. ***"
+ (Project current world == world) ifTrue: [^ false].
- (World == world) ifTrue: [^ false].
"self inform: 'Can''t send the current world out'."
world isInMemory ifFalse: [^ false]. "already done"
self projectParameters at: #isMVC put: true.
^ false "Only Morphic projects for now"
!
Item was changed:
----- Method: MVCProject>>storeSegmentNoFile (in category 'file in/out') -----
storeSegmentNoFile
"For testing. Make an ImageSegment. Keep the outPointers in memory. Also useful if you want to enumerate the objects in the segment afterwards (allObjectsDo:)"
+ (Project current world == world) ifTrue: [^ self]. " inform: 'Can''t send the current world out'."
- (World == world) ifTrue: [^ self]. " inform: 'Can''t send the current world out'."
world isInMemory ifFalse: [^ self]. "already done"
self projectParameters at: #isMVC put: true.
^ self "Only Morphic projects for now"
!
David T. Lewis uploaded a new version of MorphicTests to project The Trunk:
http://source.squeak.org/trunk/MorphicTests-dtl.43.mcz
==================== Summary ====================
Name: MorphicTests-dtl.43
Author: dtl
Time: 13 November 2017, 8:55:25.971745 pm
UUID: 668f9891-fbaa-4aa6-ad4b-28aff8fab813
Ancestors: MorphicTests-tpr.42
Remove unnecessary reference to global World.
=============== Diff against MorphicTests-tpr.42 ===============
Item was changed:
----- Method: MorphicUIManagerTest>>findWindowInWorldLabeled: (in category 'private') -----
findWindowInWorldLabeled: aLabel
"Look in the world and in the hand for windows. Yes, windows may spawn in the hand."
+ | world |
+ world := Project current world.
+ ^ world submorphs, (world hands gather: [:hand | hand submorphs])
-
- ^ World submorphs, (World hands gather: [:hand | hand submorphs])
detect: [ :each |
each isSystemWindow
and: [ each label = aLabel ] ]
ifNone: [].!