this documentation is work-in-progress, edit here (md).

Strings

sections in this chapter:
Casting »
Copying »
Implicit Conversion »
[ String ] object »
[ String ] = [ String ] »
[ String ] ≠ [ String ] »
[ String ] length »
[ String ] bytes »
[ String ] + [ String ] »
[ String ] append: [ String ] »
[ String ] code »
[ String ] from: [ Number ] length: [ Number ] »
[ String ] offset: [ Number ] »
[ String ] character: [ Number ] »
[ String ] find: [ String ] »
[ String ] uppercase »
[ String ] lowercase »
[ String ] last: [ String ] »
[ String ] [ String ]: [ String ] »
[ String ] replace: [ String ] with: [ String ] »
[ String ] - [ String ] »
[ String ] contains: [ String ] »
[ String ] trim »
[ String ] number »
[ String ] boolean »
[ String ] split: [ String ] »
[ String ] characters »
[ String ] compare: [ String ] »
[ String ] < [ String ] »
[ String ] ≤ [ String ] »
[ String ] > [ String ] »
[ String ] ≥ [ String ] »
[ String ] hash: [ String ] »

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