" CS 1621 Fall 2005 This code demonstrates some cool things in Smalltalk such as files, streams, collections and the perform method. Some of this should look familiar, since Java has adopted many of these classes (albeit with different syntax and typing rules)." | s p infile instr str value msgs| s := Prompter prompt: 'File name? ' default: ''. infile := File name: s. instr := infile readStream. People := Dictionary new. msgs := Person instanceVariableString. "msgs will store the string of instance variable names so that they can be shown to the user. Note that the instance variable names don't necessarily correspond to the methods, but in this case they do" s := Prompter prompt: 'Use which key for dictionary? (', msgs, ')' default: ''. s := s asSymbol. " The perform method in Smalltalk allows method calls to vary, so the method name invoked can be determined at runtime. This behavior can be done in Java (in a slightly more complicated way) using reflection. " [instr atEnd] whileFalse: [ p := Person new. "Like Java, in Smalltalk object variables are references, so to get multiple distinct objects we need to have new here at each iteration" p getDataF: instr. People at: (p perform: s) put: p. p printString printNl. '' printNl. ]. " Now let's make a stream over a string and put the rest of the output into the string using stream operations" str := WriteStream on: String new. "Note: The dictionary (as in Java) is hashed, and thus when values are selected, they are not in any special order " value := (Prompter prompt: 'Minimum Salary? ' default: '') asInteger. " The semicolon (;) enables use to cascade messages to the same receiver, thereby saving keystrokes. See a better example in the printString method of the Person class " str nextPutAll: 'People with salaries >= ' ; nextPutAll: (value printString) ; nl. p := (People select: [ :x | (x salary >= value) ]). p do: [ :x | str nextPutAll: (x printString); nl; nl]. "If we now insert the selected items into a SortedCollection, they will be sorted on the field of our choosing" s := Prompter prompt: 'Field to sort on? (' , msgs, ')' default: ''. s := s asSymbol. str nl. str nextPutAll: 'Now with some order' ; nl. p := SortedCollection sortBlock: [:a :b | (a perform: s) < (b perform: s)]. "The sortBlock: message when used with a SoredCollection, allows the sorting criterion to be determined differently based on the comparison in the sortBlock of the two block arguments. For a Java similar ability, see the TreeMap class and the Comparator interface" People do: [ :x | (x salary >= value) ifTrue: [ p add: x] ]. p do: [ :x | str nextPutAll: (x printString) ; nl ; nl]. "Let's try it another way -- saving a few keystrokes" s := (Prompter prompt: 'Field to sort on? (' , msgs, ')' default: '') asSymbol. str nl; nextPutAll: 'Another way of doing it, sorted on '; nextPutAll: s; nl. p := (People select: [ :x | x salary >= value]) asSortedCollection: [:a :b | (a perform: s) < (b perform: s)]. p do: [ :x | str nextPutAll: (x printString) ; nl ; nl]. str contents printNl. !