This page describes some of the most useful additions for Smalltalk, you can find more of them in the CodeFooDevelopment bundle on How to access the SCG visualworks store.

Symbol » value: anObject

The simplest little extension that could possibly make a big difference. The extension allows to use symbols as unary blocks, for example you may replace

    coll do: \[ :each | each unaryMessage ]


    coll do: #unaryMessage

There is a package SymbolValue both on How to access the SCG visualworks store as well as public store. For more information, please refer to How valueable is a Symbol? by Travis Griggs.

* » asSortBlock

Answer a sort block based on the receiver, implemented as

  Symbol >> <b>asSortBlock</b>
    ^\[ :<!-- -->a :<!-- -->b | (a perform: self) <= (b perform: self) ]
 BlockClosure >> <b>asSortBlock</b>
    self numArgs = 1 ifTrue: \[ ^\[ :<!-- -->a :<!-- -->b | (self value: a) <= (self value: b) ] ].
    self numArgs = 2 ifTrue: \[ ^self ].
    self error: 'Not a sort block.' 

Please note that, to improve execution speed, CodeFoo’s actual implementation does some magic to generate an unbound block rather than a full block bound the receiver.

BlockClosure » *

Other useful extensions of blocks includes

  • assert
  • cull: arguments
  • haltIfTrue
  • millisecondsToRun
  • profile

Character » isSpace

Answer whether the receiver is a space.

CharacterArray » *

Useful extensions of strings includes

  • asCapitalized
  • asPlural
  • lastWord
  • lines
  • linesDo: aBlock
  • piecesCutWhereCamelCase
  • trimQuotes
  • trimSeparators
  • withIndefiniteArticle

in particular those dealing with pre- and suffices are very useful

  • endsWith: aString
  • removeSuffix: aString
  • removePrefix: aString
  • replaceSuffix: aString with: newSuffix
  • startsWith: aString

Collection » transitiveClosure: unaryBlock

Answer the transitive closure of the receiver, that is, all elements in the receiver plus any element reachable using the unary block. For example

    (Array with: Object) transitiveClosure: \[ :each | each subclasses ]

returns the same as

    Object withAllSubclasses

Implemented as follows

  Collection >> <b>transitiveClosure:</b> unaryBlock
    ^self species withAll: (self asSet <b>transitiveClosure:</b> unaryBlock)
  Set >> <b>transitiveClosure:</b> unaryBlock
    | closure candidates |
    closure := self species new.
    candidates := self copy.
    \[ candidates isEmpty ] whileFalse: \[
      | element |
      element := closure add: candidates removeAny.
      (unaryBlock value: element) asCollectionDo: \[ :each |
        closure find: each ifAbsent: \[ candidates add: each ] ]].

Please not that the term closure in "transitive closure" refers to the mathematics meaning of transitive closure (see Wikipedia) rather than to computer science terminology, this is very confusing and a better naming for the method is welcome.

Set » removeAny

Implemented as

  Set >> <b>removeAny</b>
    ^self remove: self any

* » asCollectionDo: aBlock

General purpose implementation of #do:, implemented as

  UndefinedObject >> <b>asCollectionDo:</b> aBlock
  Object >> <b>asCollectionDo:</b> aBlock
    aBlock value: self
  Collection >> <b>asCollectionDo:</b> aBlock
    self do: aBlock
  CharacterArray >> <b>asCollectionDo:</b> aBlock
    aBlock value: self

Please note, we assume that strings are to be treated as objects rather than as collection.

* » asCollection

Implemented analog to #asCollectionDo: as

  UndefinedObject >> <b>asCollection</b>
  Object >> <b>asCollection</b>
    ^Array with: self
  Collection >> <b>asCollection</b>
  CharacterArray >> <b>asCollection</b>
    ^Array with: self

Please note, we assume that strings are to be treated as objects rather than as collection.

Collection » *

Other useful extensions of collection include set operations,

  • cartesianProduct: aCollection
  • difference: aCollection
  • intersection: aCollection
  • union: aCollection
  • aCollection , same as #difference:

mathematical operations, such as

  • average
  • average: aBlock
  • detectHighest: sortBlock
  • detectLowest: sortBlock
  • detectMax: aBlock
  • detectMin: aBlock
  • deviation
  • maxValue: aBlock
  • minValue: aBlock
  • normalized
  • sum
  • sum: aBlock

and some special enumerations, such as

  • collectUnion: aBlock
  • count: aBlock
  • countNot: aBlock
  • cross: aCollection do: binaryBlock

SequencableCollection » *

For lists, there are more useful enumerations, such as

  • affect: aBlock
  • crossDo: binaryBlock
  • pairsDo: binaryBlock
  • triangleDiagonalDo: binaryBlock
  • triangleDo: binaryBlock
  • with: aCollection collect: binaryBlock

as well as other useful extensions, such as:

  • evenElements
  • findFirst: aBlock ifAbsent: exceptionBlock
  • findLast: aBlock ifAbsent: exceptionBlock
  • indicesOf: anElement
  • oddElements
  • reverseSort: sortBlock
  • shuffle
  • sortReverse: sortBlock, same as above

as well as more literal accessors, such as

  • second
  • third

and smart implementations of #copyFrom:to: that understand negative, as well as, out of range indices

  • sliceFrom: start to: end
  • sliceFrom: start
  • sliceTo: end

Bag » *

And finally, there are some nice extensions for bags, such as

  • associations
  • maxOccurrences
  • mostOccurring
  • sortedCounts

SequencableCollection » sliceFrom: start to: end

Answer a copy of the receiver, starting from the element at start index up to and including the element at end index. Other than #copyFrom:to:, this method does never raise a SubscriptOutOfBoundsError. Also, negative indices may be used to count indices from the collection’s end rather than start.

The method is implemented as follows

  SequeancableCollection >> <b>sliceFrom:</b> s <b>to:</b> e
    | start end |
    start := 1 max: (s positive ifTrue: \[s] ifFalse: \[self size + s + 1]).
    end := self size min: (e positive ifTrue: \[e] ifFalse: \[self size + e]).
    ((start > end) or: \[end <= 0]) ifTrue: \[^self copyEmpty: 0].
    ^self copyFrom: start to: end

For convenience, we provide #sliceFrom: and #sliceTo: as well.

Filename » *

There are some nice accessors and enumerations for filenames, either recursive or not

  • allFiles
  • allFilesDo: aBlock
  • files
  • filesDo: aBlock
Last changed by admin on 21 April 2009