A string literal is used to define a string object (also called a string value) in the source code. Obix provides three ways to define string literals:
Strings can also be created from external resources, such as text files and URLs (e.g. a text file stored on a remote server).
A quoted string literal consists of any number of Unicode characters and/or escape characters within double quotes.
Table 4.3. Quoted string literal syntax
| Production | Syntax | Links |
|---|---|---|
quoted_string_literal |
'"' ( Unicode_character | escape_character ) * '"'
remark: Unicode_character cannot be | the section called “Quoted string literal” |
Unicode_character | any Unicode_character, like A, B, C, 1, 2, 3, +, -, %, and so on | |
escape_character |
|
Example 4.7. String literals
service string_literal_example
command string_literals
script
console.message ( "Hello" ) // Hello
console.message ( "" ) // <empty string>
console.message ( "\"" ) // <quote>
console.message ( "'" ) // <apostrophe>
console.message ( "\t1" ) // <horizontal tab>1
console.message ( "\r\n" ) // <carriage return><line feed>
console.message ( "Hello\\\nTom" ) // Hello\<line feed>Tom
console.message ( "\u0038\u0039\u002f there" ) // hi? there
end
end
endExecuting the above command will display the following on the system console:
Hello " ' 1 Hello\ Tom hi? there
The quoted string literal in Obix is very similar to the classical string literal used in several popular programming languages, such as Java and C#. However, although every string can be defined using the quoted string literal, this notation suffers from the following inconveniences which occur frequently in practice:
Backslashes (\) and quotes (") must be escaped with the backslash, which makes string literals less writable and readable. This is annoying and error-prone, because backslashes are often used when specifying Windows directory and file names, quotes are always used when specifying XML attributes, and apostrophes and quotes are often used in SQL statements. For example, we cannot write:
XML_string = "<file name="c:\foo\bar.txt" />"
Instead, we have to write:
XML_string = "<file name=\"c:\\foo\\bar.txt\" />"
Moreover, escaping the backslash can become quite tricky in regular expressions, because they also escape characters with backslashes, which means that backslashes in regular expressions must be double-escaped. For example, a backslash in a regular expression becomes: \\\\.
New lines must also be escaped. Even worse, the new line in Windows is a <carriage return> followed by a <line feed>, whereas it is just a <line feed> on Linux and Unix systems. Hence, to create the following string:
line 1 line 2
we have to code:
"line 1\nline2"
on a Unix system, and:
"line 1\r\nline2"
on a Windows system.
A better approach is to use the service attribute se_string.a_new_line which automatically provides the correct new line, depending on the operating system the application is running on:
"line 1" & se_string.a_new_line & "line2"
There is no easy way to embed expressions (e.g. formatted string) within quoted string literals. We have to use the string concatenation operator, such as:
product_description = "Product " & product.identifier.to_string & "; " & product.name
However, string concatenations can dramatically decrease performance, because quoted string literals represent objects of type string, and those objects are immutable. Hence, each time a string is concatenated, a new string object must be allocated in memory. A solution is to use mutable strings instead of immutable ones, but this requires us to replace the above example of code with:
product_description = fa_mutable_string.co_create("Product ").append(product.identifier.to_string).append("; ").append(product.name).to_stringTo eliminate the above inconveniences, Obix provides other notations to define string literals, as explained in the following sections.
A triple apostrophed string literal consists of any number of Unicode characters enclosed by a pair of three apostrophes (''').
Triple apostrophed string literals are best suited whenever the string contains:
/ and ")Table 4.4. Triple apostrophed string literal syntax
| Production | Syntax | Links |
|---|---|---|
triple_apostrophed_string_literal |
"'''" Unicode_character * "'''"
remark: characters are never escaped (e.g. | the section called “Triple apostrophed string literal” |
Unicode_character | any Unicode_character, like A, B, C, 1, 2, 3, +, -, %, and so on |
The following is an excerpt of the string literal tests contained in the Obix standard library. The code should be self-explanatory. For example, the instruction:
verify '''Hello''' =v "Hello"
verifies that the string created by the triple apostrophed literal '''Hello''' has the same value as the string created by the quoted literal "Hello".
For more information about testing source code, see Chapter 21, Testing
Example 4.8. Triple apostrophed string literals
// triple apostrophed string literal tests
// simple string
verify '''Hello''' =v "Hello"
// escape characters
// He said: "She said: 'How're you?'"
verify '''He said: "She said: 'How're you?'"''' =v "He said: \"She said: 'How're you?'\""
// file = "c:\foo\bar.txt"
verify '''file = "c:\foo\bar.txt"''' =v "file = \"c:\\foo\\bar.txt\""
// SELECT "customers"."name" from "customers" where "city" = 'Deland'
verify '''SELECT "customers"."name" from "customers" where "city" = 'Deland'''' =v &
"SELECT \"customers\".\"name\" from \"customers\" where \"city\" = 'Deland'"
// multi-line strings
// line 1
// line 2
verify '''line1
line2''' =v "line1" & se_string.a_new_line & "line2"
//
// line 1
// line 2
// line 3
//
verify '''
line1
line2
line3
''' =v se_string.a_new_line & "line1" & se_string.a_new_line & "line2" & se_string.a_new_line & "line3" & se_string.a_new_line
// special cases
// empty string
verify '''''' =v ""
// single characters
verify '''a''' =v "a"
verify '''\''' =v "\\"
verify '''"''' =v "\""
verify ''' ''' =v " "
verify ''''''' =v "'"
// weird
verify '''\/''' =v "\\/"
verify '''\\\""\\\''' =v "\\\\\\\"\"\\\\\\"
A triple quoted string literal consists of any number of Unicode characters enclosed by a pair of three quotes (").
Triple quoted string literals extend the notation of the triple apostrophed string literal by adding the possibility to embed expressions that are evaluated at runtime. Hence, they are well suited to define strings that will be dynamically created at runtime.
Expressions are embedded between {{ and }} (two opening curly braces and two closing curly braces). The text between the opening and closing curly braces can be any valid expression that must evaluate to a non void object of type string.
Table 4.5. Triple quoted string literal syntax
| Production | Syntax | Links |
|---|---|---|
triple_quoted_string_literal |
'"""' ( Unicode_character | embedded_string_literal_expression ) * '"""'
remark: characters are never escaped (e.g. | the section called “Triple quoted string literal” |
Unicode_character | any Unicode_character, like A, B, C, 1, 2, 3, +, -, %, and so on | |
embedded_string_literal_expression |
"{{" expression "}}"
remark: | the section called “Triple quoted string literal” |
The following is an excerpt of the string literal tests in the Obix standard library:
Example 4.9. Triple quoted string literals
// triple quoted string literal tests
// simple string
verify """Hello""" =v "Hello"
// escape characters
// He said: "She said: 'How're you?'"
verify """He said: "She said: 'How're you?'"""" =v "He said: \"She said: 'How're you?'\""
// file = "c:\foo\bar.txt"
verify """file = "c:\foo\bar.txt"""" =v "file = \"c:\\foo\\bar.txt\""
// SELECT "customers"."name" from "customers" where "city" = 'Deland'
verify """SELECT "customers"."name" from "customers" where "city" = 'Deland'""" =v &
"SELECT \"customers\".\"name\" from \"customers\" where \"city\" = 'Deland'"
// multi-line strings
// line 1
// line 2
verify """line1
line2""" =v "line1" & se_string.a_new_line & "line2"
//
// line 1
// line 2
// line 3
//
verify """
line1
line2
line3
""" =v se_string.a_new_line & "line1" & se_string.a_new_line & "line2" & se_string.a_new_line & "line3" & se_string.a_new_line
// embedded expressions
const string first_name = "Linus"
verify """Hi {{c_first_name}}!""" =v "Hi Linus!"
// triple apostrophed strings cannot contain embedded expressions
verify '''Hi {{c_first_name}}!''' =v "Hi {{c_first_name}}!"
const positive32 identifier = 123
const string last_name = "Torvalds"
const string embedded = """
<person id="{{ (identifier + 1).to_string }}">
<first_name>{{first_name}}</first_name>
<last_name>{{last_name}}</last_name>
</person>"""
const string non_embedded = '''
<person id="124">
<first_name>Linus</first_name>
<last_name>Torvalds</last_name>
</person>'''
verify embedded =v non_embedded
// following instruction will not compile
//console.message("""{{void}}""")
var string void_string = void
// following instruction will produce runtime error
console.message("""{{void_string}}""") on_error:continue
verify v_program_error_ #r void
![]() | Note |
|---|---|
| This kind of string literal is not yet available at the time of writing and will possibly appear in a future version of Obix. |
The idea of the configurable string literal is to extend the notation of the triple quoted string literal by adding the possibility to specify any arbitrary text used to
Configurable string literals should be needed rarely in practice. A concrete example would be source code that defines a string which represents itself source code containing triple quoted strings.
Besides the possibility to hardcode string literals in the source code, Obix provides a number of ways to get strings from external resources, such as text files or URL contents. However, the scope of this chapter is not to fully describe these possibilities. For further information, please refer to the API documentation.
Here is a simple example (without file input/output error handling):
Example 4.10. Getting strings from external resources
// read text from text file into string (error handling code omitted for brevity) var string text_in_file = fa_string.co_create_from_text_file_name.o_result ( '''c:\Documents and Settings\Jerome\My Documents\text_file.txt''' ) // display text on screen se_console.co_message ( "contents of file: " & v_text_in_file ) // save text to another file (create copy of text file) v_text_in_file.co_store_to_new_or_existing_file ( fa_file_handle.co_create ( '''d:\copy of text_file.txt''' ) )