Strings
Each time a text is placed between quotation marks ['...'] , Xoscript will create a new stringobject for you. However, make sure to use the correct quotation marks. The quotation mark at the beginning of the text differs from the one at the end.
Casting
You can create a copy of each object with a different type by using the following messages:
| Message | Result |
|---|---|
| number | Converts an object into a number |
| text | Converts an object into text |
| bool | Converts an object into a boolean object (True or False) |
The following rules apply:
| message | None | Bool | Number | Text | Other |
|---|---|---|---|---|---|
| bool | False | n/a | 0→False else→True | True | Mostly True |
| number | 0 | False→0 True→1 | n/a | ['n']→n | Mostly 1 |
| string | ['None'] | ['False']/['True'] | ['n'] | n/a | Depends |
Copying
Values in Xoscript are always passed by reference. In other languages it depends on the type of value, in Xoscript there is only one way, by reference. Xoscript never makes a copy of a value. To copy an object, you need to send the message copy.
>> sheep := ['Dolly'].
>> clone := sheep.
clone replace: ['l'] with: ['n'].
Out write: sheep, stop.
output:
Donny
Here, you might have expected that the output would be Dolly, instead of Donny. However, this is not the case as both names refer to the same object. When working with a loop, something similar occurs:
>> points := List new ; 1 ; 2 ; 3.
points each: { :number :quantity quantity add: 1. }.
Out write: points, stop.
output:
List ← 2 ; 3 ; 4
In fact, Xoscript always uses references, so on :quantity the above-illustrated loop also indicates the reference to the element in the sequence.
In order to copy an object, you have to specify this action explicitly:
>> sheep := ['Dolly'].
>> clone := sheep copy.
clone replace: ['l'] with: ['n'].
Out write: sheep, stop.
output:
Dolly
By sending the unary message copy to a string, the object returns a copy of that same string object. It is possible to copy Number objects, boolean objects, lists and dicts in the same way.
You can also define your own copy implementation, this is even a neccesity if you create your own objects. The default implementation of copy for a list makes a shallow copy, it creates a new list with the same elements.
>> a := List new ; 1 ; 2 ; 3.
>> b := a copy ; 4.
Out write: a, stop
write: b, stop.
output:
List ← 1 ; 2 ; 3
List ← 1 ; 2 ; 3 ; 4
In this case, 4 is added only to the copy. However, because the copy is shallow, the objects in both sequences are the same.
>> sheep := List new ; ['Dolly'] ; ['Shaun'].
>> clones := sheep copy.
clones each: { :number :sheep
sheep append: ['2'].
}.
Out write: sheep, stop.
Out write: clones, stop.
output:
List ← ['Dolly2'] ; ['Shaun2']
List ← ['Dolly2'] ; ['Shaun2']
So if we append 2 to each name in the copy, the original sequence is affected as well.
To remedy this we need to make a deep copy. Such a copy action for a list could be composed as follows:
List on: ['copy'] do: {
>> copy := List new.
self each: { :number :section
copy append: section recursive copy.
}.
<- copy.
}.
>> sheep := List new ; ['Dolly'] ; ['Shaun'].
>> clones := sheep copy.
clones each: { :number :sheep
sheep append: ['2'].
}.
Out write: sheep, stop.
Out write: clones, stop.
output:
List ← ['Dolly'] ; ['Shaun']
List ← ['Dolly2'] ; ['Shaun2']
Also, note the message recursive, this message is necessary to send before the copy message.
It is essential to keep in mind that although a copy of an object often has the same appearance of the original, it will, in fact, never be the same. The root object defines a message equal:, which can be used to compare the identity of objects. Take a look at the following example:
>> a := 1.
>> b := a copy.
>> c := a.
Out write: a = b, stop.
Out write: a = c, stop.
Out write: ( a equals: b ), stop.
Out write: ( a equals: c ), stop.
output:
True
True
False
True
Implicit Conversion
Xoscript uses implicit conversion to convert objects. To print a list on screen, Xoscript will, for example, send the message string internally to the list. This can proof very useful, in case you would like to print a sequence as a comma-separated list. The message string can be overwritten:
>> csv := List new ; 1 ; 2 ; 3.
csv on: ['string'] do: {
<- self combine: [','].
}.
Out write: csv, stop.
output:
1,2,3
[ String ] object
example:
>> x := List ← 1 ; 2 ; 3.
>> a := x string.
>> b := a object.
Out write: a type, stop.
Out write: a, stop.
Out write: b type, stop.
Out write: b, stop.
output:
String
List ← 1 ; 2 ; 3
List
List ← 1 ; 2 ; 3
[ String ] = [ String ]
example:
>> x := ['abc'] = ['abc'].
Out write: x, stop.
>> x := ['abc'] = ['xxx'].
Out write: x, stop.
output:
True
False
[ String ] ≠ [ String ]
example:
>> x := ['abc'] = ['abc'].
Out write: x, stop.
>> x := ['abc'] ≠ ['xxx'].
Out write: x, stop.
output:
True
True
[ String ] length
example:
>> x := ['☘☘☘'].
Out write: x length, stop.
output:
3
[ String ] bytes
example:
>> x := ['☘☘☘'].
Out write: x bytes, stop.
output:
9
[ String ] + [ String ]
example:
>> x := ['ABC'].
>> y := ['DEF'].
>> z := x + y.
Out write: z, stop.
output:
ABCDEF
[ String ] append: [ String ]
example:
>> x := ['123'].
x append: ['456'].
Out write: x, stop.
output:
123456
[ String ] code
example:
>> x := ['qwerty'].
Out write: x code, stop.
output:
['qwerty']
[ String ] from: [ Number ] length: [ Number ]
example:
>> x := ['qwerty'] from: 2 length: 3.
Out write: x, stop.
output:
ert
[ String ] offset: [ Number ]
example:
>> x := ['qwerty'] offset: 2.
Out write: x, stop.
output:
erty
[ String ] character: [ Number ]
example:
Out write: (['.☘.'] character: 1), stop.
output:
☘
[ String ] find: [ String ]
example:
>> x := ['abc'] find: ['b'].
Out write: x, stop.
output:
1
[ String ] uppercase
example:
Out write: ['abc'] upper, stop.
output:
ABC
[ String ] lowercase
example:
>> x := ['ABC'] lower.
Out write: x, stop.
output:
abc
[ String ] last: [ String ]
example:
>> x := ['abca'] last: ['a'].
Out write: x, stop.
output:
3
[ String ] [ String ]: [ String ]
example:
Out stop.
Out stop.
Out stop.
output:
[ String ] replace: [ String ] with: [ String ]
example:
>> x := ['1...2...3'].
x replace: ['...'] with: [','].
Out write: x, stop.
output:
1,2,3
[ String ] - [ String ]
example:
>> x := ['1...2...3...'] - ['...'].
Out write: x, stop.
output:
1...2...3
[ String ] contains: [ String ]
example:
>> x := ['abc'] contains: ['a'].
>> y := ['abc'] contains: ['z'].
Out write: x, stop.
Out write: y, stop.
output:
True
False
[ String ] trim
example:
>> x := [' x '].
Out write: x trim, stop.
output:
x
[ String ] number
example:
>> x := ['12345678'].
>> y := x number.
Out write: x, stop.
Out write: y, stop.
Out write: x type, stop.
Out write: y type, stop.
output:
12345678
12345678
String
Number
[ String ] boolean
example:
Out write: [''] bool, stop.
Out write: [' '] bool, stop.
Out write: ['abc'] bool, stop.
Out write: ['123'] bool, stop.
output:
False
True
True
True
[ String ] split: [ String ]
example:
>> x := ['1,2,3'] split: [','].
Out write: x, stop.
output:
List ← ['1'] ; ['2'] ; ['3']
[ String ] characters
example:
>> x := ['123'] characters.
Out write: x, stop.
output:
List ← ['1'] ; ['2'] ; ['3']
[ String ] compare: [ String ]
example:
>> x := ['abc'].
>> y := ['def'].
>> z := x compare: y.
>> q := y compare: x.
Out write: z, stop.
Out write: q, stop.
output:
-1
1
[ String ] < [ String ]
example:
Out write: (['abc'] < ['def']), stop.
Out write: (['def'] < ['abc']), stop.
output:
True
False
[ String ] ≤ [ String ]
example:
Out write: (['abc'] ≤ ['def']), stop.
Out write: (['def'] ≤ ['abc']), stop.
output:
True
False
[ String ] > [ String ]
example:
Out write: (['abc'] > ['def']), stop.
Out write: (['def'] > ['abc']), stop.
output:
False
True
[ String ] ≥ [ String ]
example:
Out write: (['abc'] ≥ ['def']), stop.
Out write: (['def'] ≥ ['abc']), stop.
output:
False
True
[ String ] hash: [ String ]
example:
>> x := ['123'].
>> y := x hash: ['1234567890123456'].
Out write: x, stop.
Out write: y, stop.
output:
123
18108683157783875119