"-*- smalltalk -*-" " @@PLEAC@@_NAME " " @@SKIP@@ Smalltalk @@SKIP@@ " " @@PLEAC@@_1.0 " "In Smalltalk, everything is an object. Including strings. Strings are instances of the class String." |string| string := '\n'. "Two Characters, \ and an n - literal form" string := String with: $\ with: $n. "As above, but creating the string by passing messages" string := 'Jon ''Maddog'' Orwant'. "Literal string containing single quotes" string := String with: Character cr. "String with a newline character" string := 'Jon "Maddog" Orwant'. "Literal string containing double quotes" "ANSI standard Smalltalk does not allow arbitrary literal string delimiters" "Reading a stream of characters up to (but not including) 'EOF'. Most String handling in Smalltalk is done using streams (instances of class Stream or one of its subclasses." |sourceStream a| sourceStream := ReadStream on: 'This is a multiline here document terminated by EOF on a line by itself EOF'. a := sourceStream upToAll: 'EOF'. " @@PLEAC@@_2.1 " "Even numbers are objects in Smalltalk. There is no special syntax for manipulating numbers other than the literal forms of numbers. For example, evaluating '1 + 2' results in the object 1 being sent the message '+' with the single argument 2. The '+' method returns the object 3. An object is either a subclass of Number (in which case it is a number) or it's not. An instance of String is not a number, though it might contain the literal form of a number. So let's say we have an instance of class String which we think might contain a number in some form or other..." |result| result := '123.45' isNumber. "false is assigned to result. '123.45' is a String, not a Number." result := 123.45 isNumber. "true is assigned to result. 123.45 is indeed a number." result := Number readFrom: ('123.45' readStream). "result is the Fraction(!) 2469/20" result := result asFloat. "result is now the Float 123.45" result := Number readFrom: ('this is not a number' readStream). "result is the Integer zero." result := Number readFrom: ('123abc' readStream). "result is the Integer 123" result := 'This is not a number' isNumeric. "result is false" result := '123' isNumeric. "result is true" result := '123abc' isNumeric. "result is false" result := '123' asNumber. "result is the Integer 123" |number result| number := '123' asNumber. result := number isInteger. "result is true" result := number isRational. "result is true" number := 123 / 456. "result is the Fraction 41/152" result := number isInteger. "result is false" result := number isRational. "result is true" "Other tests that all Number objects respond to are: >>isFinite >>isInfinite >>odd >>positive" " @@PLEAC@@_3.0 " "Dates and time are objects in Smalltalk too ... of course!" Date today. "Evaluates to an instance of class Date." Time now. "Evaluates to an instance of class Time." DateTime now. "Evaluates to an instance of class DateTime." "Here are some examples of the messages that DateTime responds to instances of Date and Time respond to similar messages as appropriate." |myDateTime| myDateTime := DateTime now. myDateTime second. " - the seconds part of the DateTime. An Integer" myDateTime minute. " - the minutes part" myDateTime hour. "- the hours part 24hr clock by default" myDateTime hour24. "- as above, but explicitly the 24 hours clock" myDateTime hour12. "- as above but with 12 hours clock" myDateTime dayOfWeek. " - the integer day index. 1=Sunday" myDateTime dayOfWeekName. "- day of the week as a Symbol, e.g. #Tuesday" myDateTime dayOfMonth. "- day of the month - an Integer." myDateTime month. "- month of the year. Month index - an integer." myDateTime monthName. "- name of the month as a Symbol, e.g. #June" myDateTime year. " - the year number as an Integer, e.g. 2005" myDateTime dayOfYear. "- integer day number of the day within the year." "... and many more. See the DateTime, Date and Time classes for the full story." " @@PLEAC@@_3.1 " "We saw Date, Time and DateTime objects being created in the introduction. Let's now see how we can show the value of these objects." Date today printString. " -> '3-Jun-2005' " Time now printString. " -> '22:09:35' " DateTime now printString. " -> ' 2005-06-03T22:10:22+10:00' " "The message >>printString can be sent to any object. It is up to the object to return an interesting instance of class String." " @@PLEAC@@_3.2 " "We can create arbitrary dates and time using other class methods on the Date, Time and DateTime classes." |myDateTime| "The following creates a DateTime of the time I wrote this code as if it was GMT" myDateTime := DateTime year: 2005 month: 6 day: 3 hour: 22 minute: 18 second: 26. "The following creates the DateTime with the correct offset for Sydney, Australia." myDateTime := DateTime year: 2005 month: 6 day: 3 hour: 22 minute: 18 second: 26 offset: (Duration days: 0 hours: 10 minutes: 0 seconds: 0). "And now we can get the seconds from myDateTime." myDateTime asSeconds. "Evaluates to an Integer" myDateTime asSeconds printString. "Evaluates to an instance of String representing the above integer." " @@PLEAC@@_3.3 " "We can also create a Dates and Times from a number of seconds" | myDateTime aNumberOfSeconds aDate aTime| myDateTime := DateTime year: 2005 month: 6 day: 3 hour: 22 minute: 18 second: 26 offset: (Duration days: 0 hours: 10 minutes: 0 seconds: 0). aNumberOfSeconds := myDateTime asSeconds. aDate := Date fromSeconds: aNumberOfSeconds. aTime := Time fromSeconds: aNumberOfSeconds. " @@PLEAC@@_4.0 " "Arrays are also objects in Smalltalk. The class Array is a subclass (though not an immediate subclass) of Collection. All collections share enumeration and mutation abilities, though some kinds of collection impose limits. For example, Arrays are of a fixed size, so it is not possible to add more elements to an Array than it's current size - with other kinds of collection, any number of elements can be added (until you hit a system limit, like running out of memory)." "Arrays have a literal form, unlike other kinds of collection." |myArray| "First we assign a litteral Array containing four Strings to the variable myArray." myArray := #('this' 'that' 'the' 'other'). "Now we create a nested Array in a similar way. We end up with an Array with three elements, the first two being Strings and the third being a distinct instance of class Array in turn containing two Strings." myArray := #('this' 'that' #('the' 'other')). "We can also create arrays by message passing. So, to repeat the last last example:" |outer nested| nested := Array with: 'the' with: 'other'. outer := Array with: 'this' with: 'that' with: nested. " @@PLEAC@@_4.1 " |a lines| a := #('quick' 'brown' 'fox'). "The following send >>subStrings to a String. The result of this is an OrderedCollection with 5 elements, each element being a String. To get an Array, we send >>asArray to the OrderedCollection." a := 'Why are you teasing me?' subStrings asArray. "In the next example I'm forcing the cr character into the string to make the code work either from a code file, or in an image workspace. The cr in a literal String *should* be respected, but in GNU Smalltalk 2.1.8 it does not seem to be in an image worksheet." lines := ( ('The boy stood on the burning deck.%1' bindWith: Character cr), 'It was as hot as glass.' subStrings: Character cr) asArray. "Here we create a large array by reading the contents of a file. The contents of the file is an instance of class String in this case. >>contents is crude, but works fine in this case ... if you have a file called 'mydatafile' in the current directory that contains printable characters." |bigArray| bigArray := ((File name: 'mydatafile') contents) asArray. "Now we concatenate some Strings and convert them to Arrays" |name banner| name := 'Gandalf'. banner := ('Speak, ', name, ', and enter!') asArray. banner := ('Speak, %1, and enter!' bindWithArguments: (Array with: name)) asArray.