Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-cmm.1018.mcz
==================== Summary ====================
Name: Collections-cmm.1018 Author: cmm Time: 12 July 2022, 8:02:42.503867 pm UUID: 1cb21ed1-20f1-4d6b-8781-dbf2cd05daa1 Ancestors: Collections-cmm.1017
Restore most of the efficiency of String>>#format: when used with only numeric tokens.
=============== Diff against Collections-cmm.1017 ===============
Item was changed: ----- Method: String>>format: (in category 'formatting') ----- format: aCollection "Substitute tokens in the receiver with element values of aCollection. The tokens are indicated in curly-braces and may be either numeric, e.g., {1}, {2}, etc. and map to a SequenceableCollection, OR, alphanumeric, e.g., {name}, {date}, etc., in which case aCollection should be a Dictionary. The values can be static or, with the specification of a Block element, dynamic. Simplest examples: 'foo {date} bar' format: ({'date'->Date today} as: Dictionary).
Dynamic calculation is allowed via Blocks. 'foo {NOW} bar' format: ({'NOW'-> [DateAndTime now]} as: Dictionary).
Backward-compatible with numeric-only #format: 'foo {1} bar' format: {Date today}.
Now with block support: 'foo {1} bar' format: {[Date today]}. Complete example with escaped characters: '{ } \ foo {1} bar {2}' format: {12. 'string'}. + '{ } \ foo {FOO} bar {BAR}' format: ({'FOO'->12. 'BAR'->'string'} as: Dictionary)." + ^ self class + new: self size * 11 // 10 "ready for +10% growth" + streamContents: - '{ } \ foo {FOO} bar {BAR}' format: ({'FOO'->12. 'BAR'->'string'} as: Dictionary). - " - ^ self class new: self size * 11 // 10 "ready for +10% growth"streamContents: [ : output | | lastIndex nextIndex key | lastIndex := 1. + key := 0. - key := WriteStream on: (String new: 10). [ "stream to output until first { or " (nextIndex := self indexOfAnyOf: FormatCharacterSet startingAt: lastIndex) = 0 ] whileFalse: [ nextIndex = lastIndex ifFalse: [ output next: nextIndex - lastIndex putAll: self startingAt: lastIndex ]. "special char hit, escape char?" (self at: nextIndex) == $\ + ifTrue: + [ "transfer the escaped character. " - ifTrue: [ "transfer the escaped character." output nextPut: (self at: (nextIndex := nextIndex + 1)) ] ifFalse: [ | nextKeyChar | "${ char, parse the key" [ nextKeyChar := self at: (nextIndex := nextIndex + 1). + nextKeyChar isAlphaNumeric ] whileTrue: + [ (key isInteger and: [ nextKeyChar isDigit ]) + ifTrue: [ key := key * 10 + nextKeyChar digitValue ] + ifFalse: + [ key isInteger ifTrue: + [ key := WriteStream with: + (key isZero + ifTrue: [ String empty ] + ifFalse: [ key asString ]) ]. + key nextPut: nextKeyChar ] ]. - nextKeyChar isAlphaNumeric ] whileTrue: [ key nextPut: nextKeyChar ]. nextKeyChar = $} ifFalse: [ self error: '$} expected' ]. + key isInteger + ifTrue: + [ output nextPutAll: (aCollection at: key) value asString. + key := 0 ] + ifFalse: + [ output nextPutAll: (aCollection at: key contents) value asString. + key reset ] ]. - output nextPutAll: (aCollection at: key contents numberOrValue) value asString. - key reset ]. lastIndex := nextIndex + 1 ]. lastIndex <= self size ifTrue: + [ output next: self size - lastIndex + 1 putAll: self startingAt: lastIndex ] ]! - [ output - next: self size - lastIndex + 1 - putAll: self - startingAt: lastIndex ] ]!
Item was removed: - ----- Method: String>>numberOrValue (in category 'formatting') ----- - numberOrValue - "If I'm 100% digits, answer my numerical value, otherwise, answer myself." - | number | - number := 0. - self size - to: 1 - by: -1 - do: - [ : pos | | digit | - digit := self at: pos. - digit isDigit ifFalse: [ ^ self ]. - number := number + ((10 raisedTo: self size - pos) * digit digitValue) ]. - ^ number!
packages@lists.squeakfoundation.org