Strings
Each time a text is placed between blocks and 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 (this allows you to use the single quote without needing to escape it).
UTF8
Strings in xoscript usually contain utf8 encoded text. Although it’s technically possible to have binary or non-utf8 content in a string, it is recommended to use blobs for that. Blobs are provided by the server plugin (see chapter ffi). In general blobs/ffi are provided on a plugin/platform basis, since they tie into the platform and architecture (ffi/blobs). The core of the scripting language tries to remain as platform agnostic as possible.
Casting
You can create a copy of each object with a different type by using the following messages:
| Message | Result |
|---|---|
| number | Converts to a number |
| string | Converts to a string |
| bool | Converts to a boolean |
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.
Example:
>> sheep := ['Dolly'].
>> clone := sheep.
clone replace: ['l'] with: ['n'].
Out write: sheep, stop.
Result:
automatically generated from test: #611Here, 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:
Example:
>> points := List new ; 1 ; 2 ; 3.
points each: { :number :quantity quantity add: 1. }.
Out write: points, stop.
Result:
automatically generated from test: #612In fact, Xoscript always uses references, so on :quantity the above-illustrated loop also indicates the reference to the element in the list.
In order to copy an object, you have to specify this action explicitly:
Example:
>> sheep := ['Dolly'].
>> clone := sheep copy.
clone replace: ['l'] with: ['n'].
Out write: sheep, stop.
Result:
automatically generated from test: #613By 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.
Example:
>> a := List new ; 1 ; 2 ; 3.
>> b := a copy ; 4.
Out write: a, stop
write: b, stop.
Result:
automatically generated from test: #614In this case, 4 is added only to the copy. However, because the copy is shallow, the objects in both lists are the same.
Example:
>> sheep := List new ; ['Dolly'] ; ['Shaun'].
>> clones := sheep copy.
clones each: { :number :sheep
sheep append: ['2'].
}.
Out write: sheep, stop.
Out write: clones, stop.
Result:
automatically generated from test: #615So if we append 2 to each name in the copy, the original list 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:
Example:
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.
Result:
automatically generated from test: #616Also, 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:
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.
Result:
automatically generated from test: #617Implicit 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 list as a comma-separated list. The message string can be overwritten:
Example:
>> csv := List new ; 1 ; 2 ; 3.
csv on: ['string'] do: {
<- self combine: [','].
}.
Out write: csv, stop.
Result:
automatically generated from test: #620[ 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.
Result:
automatically generated from test: #460
[ String ] = [ String ]
Example:
>> x := ['abc'] = ['abc'].
Out write: x, stop.
>> x := ['abc'] = ['xxx'].
Out write: x, stop.
Result:
automatically generated from test: #461
[ String ] !=: [ String ]
Example:
>> x := ['abc'] = ['abc'].
Out write: x, stop.
>> x := ['abc'] ≠ ['xxx'].
Out write: x, stop.
Result:
automatically generated from test: #462
[ String ] length
Example:
>> x := ['☘☘☘'].
Out write: x length, stop.
Result:
automatically generated from test: #463
[ String ] bytes
Example:
>> x := ['☘☘☘'].
Out write: x bytes, stop.
Result:
automatically generated from test: #464
[ String ] + [ String ]
Example:
>> x := ['ABC'].
>> y := ['DEF'].
>> z := x + y.
Out write: z, stop.
Result:
automatically generated from test: #465
[ String ] append: [ String ]
Example:
>> x := ['123'].
x append: ['456'].
Out write: x, stop.
Result:
automatically generated from test: #466
[ String ] code
Example:
>> x := ['qwerty'].
Out write: x code, stop.
Result:
automatically generated from test: #467
[ String ] from: [ Number ] length: [ Number ]
Example:
>> x := ['qwerty'] from: 2 length: 3.
Out write: x, stop.
Result:
automatically generated from test: #468
[ String ] offset: [ Number ]
Example:
>> x := ['qwerty'] offset: 2.
Out write: x, stop.
Result:
automatically generated from test: #469
[ String ] character: [ Number ]
Example:
Out write: (['.☘.'] character: 1), stop.
Result:
automatically generated from test: #470
[ String ] find: [ String ]
Example:
>> x := ['abc'] find: ['b'].
Out write: x, stop.
Result:
automatically generated from test: #471
[ String ] uppercase
Example:
Out write: ['abc'] upper, stop.
Result:
automatically generated from test: #472
[ String ] lowercase
Example:
>> x := ['ABC'] lower.
Out write: x, stop.
Result:
automatically generated from test: #473
[ String ] last: [ String ]
Example:
>> x := ['abca'] last: ['a'].
Out write: x, stop.
Result:
automatically generated from test: #474
[ String ] [ String ]: [ String ]
Example:
>> x := ['1...2...3'].
x replace: ['...'] with: [','].
Out write: x, stop.
Result:
automatically generated from test: #476
[ String ] replace: [ String ] with: [ String ]
Example:
>> x := ['1...2...3'].
x replace: ['...'] with: [','].
Out write: x, stop.
Result:
automatically generated from test: #476
[ String ] - [ String ]
Example:
>> x := ['1...2...3...'] - ['...'].
Out write: x, stop.
Result:
automatically generated from test: #477
[ String ] contains: [ String ]
Example:
>> x := ['abc'] contains: ['a'].
>> y := ['abc'] contains: ['z'].
Out write: x, stop.
Out write: y, stop.
Result:
automatically generated from test: #478
[ String ] trim
Example:
>> x := [' x '].
Out write: x trim, stop.
Result:
automatically generated from test: #479
[ 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.
Result:
automatically generated from test: #480
[ String ] boolean
Example:
Out write: [''] bool, stop.
Out write: [' '] bool, stop.
Out write: ['abc'] bool, stop.
Out write: ['123'] bool, stop.
Result:
automatically generated from test: #481
[ String ] split: [ String ]
Example:
>> x := ['1,2,3'] split: [','].
Out write: x, stop.
Result:
automatically generated from test: #482
[ String ] characters
Example:
>> x := ['123'] characters.
Out write: x, stop.
Result:
automatically generated from test: #483
[ String ] byte
Example:
# returns the 1st byte of a string
Out write: ['A'] byte, stop.
Result:
automatically generated from test: #688
[ String ] compare: [ String ]
Example:
>> x := ['abc'].
>> y := ['def'].
>> z := x compare: y.
>> q := y compare: x.
Out write: z, stop.
Out write: q, stop.
Result:
automatically generated from test: #484
[ String ] tccompare: [ String ]
Example:
Out write: (['abc'] tccompare: ['abc']), stop.
Out write: (['abc'] tccompare: ['abx12345']), stop.
Out write: (['abx12345'] tccompare: ['abc']), stop.
Result:
automatically generated from test: #632
[ String ] < [ String ]
Example:
Out write: (['abc'] < ['def']), stop.
Out write: (['def'] < ['abc']), stop.
Result:
automatically generated from test: #485
[ String ] <=: [ String ]
Example:
Out write: (['abc'] ≤ ['def']), stop.
Out write: (['def'] ≤ ['abc']), stop.
Result:
automatically generated from test: #486
[ String ] > [ String ]
Example:
Out write: (['abc'] > ['def']), stop.
Out write: (['def'] > ['abc']), stop.
Result:
automatically generated from test: #487
[ String ] >=: [ String ]
Example:
Out write: (['abc'] ≥ ['def']), stop.
Out write: (['def'] ≥ ['abc']), stop.
Result:
automatically generated from test: #488
[ String ] hash: [ String ]
Example:
>> x := ['123'].
>> y := x hash: ['1234567890123456'].
Out write: x, stop.
Out write: y, stop.
Result:
automatically generated from test: #489
[ Format ] new apply: [ String ]
Example:
Server init.
Out write: (
Format new: ['Number format: %06.0f \n'],
apply: 56),
stop.
Result:
automatically generated from test: #536
[ Format ] apply-int: [ Number ]
Example:
>> hex := Format new: ['%x'].
# write 10
Out write: Hx xA, stop.
# make it easy to write numbers as hex
Number on: ['as-hex'] do: {
<- hex apply-int: self.
}.
# write
Out write: Hx xA as-hex, stop.
Out write: Hx xFF as-hex, stop.
Result:
automatically generated from test: #718
Server strings
The following String features are added by the Server plugin.
[ String ] ipv4?
Example:
# Server plugin required
Server init.
Out write: ['127.0.0.1'] ipv4?, stop.
Out write: ['1.2.3'] ipv4?, stop.
Result:
automatically generated from test: #684
[ String ] ipv6?
Example:
# Server plugin required
Server init.
Out write: ['fe80::1a2b:3c4d:5e6f:7a8b'] ipv6?, stop.
Out write: ['::1'] ipv6?, stop.
Out write: ['1234::5678::9abc'] ipv6?, stop.
Out write: ['12345::1'] ipv6?, stop.
Result:
automatically generated from test: #685
[ String ] mac?
Example:
# Server plugin required
Server init.
Out write: ['00:1A:2B:3C:4D:5E'] mac?, stop.
Result:
automatically generated from test: #686
[ String ] html
Example:
Server init.
# convert simple markup to html
# * = bold
# _ = italic
# newlines = br
Out write: ['
hello
everyone
this *is* _a_ test!
'] html, stop.
Result:
automatically generated from test: #687
[ String ] url-encode
Example:
Server init.
Out write: ['hello world'] url-encode, stop.
Result:
automatically generated from test: #694
[ String ] form-encode
Example:
Server init.
Out write: ['hello world'] form-encode, stop.
Result:
automatically generated from test: #695
[ String ] base64-encode
Example:
Server init.
>> a := ['{base64!}'] base64-encode.
Out write: a, stop.
Result:
automatically generated from test: #696
[ String ] base64-decode
Example:
Server init.
>> a := ['{base64!}'] base64-encode.
Out write: a base64-decode, stop.
Result:
automatically generated from test: #697
[ String ] html-encode
Example:
Server init.
Out write: ['<html>'] html-encode.
Result:
automatically generated from test: #699