3.21. kink/STR

Companion mod for str vals.

3.21.1. type str

A str is a finite immutable sequence of Unicode codepoints. Codepoints are called runes in Kink, likewise in Go.

Str.op_add(Arg_str)

Str.op_add makes a str containing the runes of Str on the front, and the runes of Arg_str on the back.

Arg_str must be a str

Example:

:Str <- 'foo' + 'bar'
stdout.print_line(Str.repr) # => "foobar"

Str.runes

Str.runes returns a vec of the runes of the Str.

Example:

stdout.print_line('xyz'.runes.repr) # => [120 121 122]

Str.empty?

Str.empty? returns whether the Str contains one or more runes.

Str.size

Str.size returns the number of runes in the Str.

The result is an int num.

Str.get(Rune_index)

Str.get returns the rune specified by Rune_index.

The result is an int num which represents the rune.

Example:

stdout.print_line('xyz'.get(0).repr) # => 120

Str.slice(From_pos To_pos)

Str.slice returns the specified slice of the Str.

Preconditions:

• From_pos and To_pos must be int nums in the range [0, Str.size]

• From_pos must be less than or equal to To_pos

The result is a str the runes of which are copied from the slice of the Bin.

Example:

:Str <- 'foobar'
:Slice <- Str.slice(1 4)
stdout.print_line(Slice.repr) # => "oob"

Str.take_front(N)

Str.take_front makes a str containing the first N runes of the Str.

N must be an int num in the range [0, Str.size].

Example:

stdout.print_line('foobar'.take_front(2).repr)  # => "fo"

Str.take_back(N)

Str.take_back makes a str containing the last N runes of the Str.

N must be an int num in the range [0, Str.size].

Example:

stdout.print_line('foobar'.take_back(2).repr)  # => "ar"

Str.drop_front(N)

Str.drop_front makes a str dropping the first N runes of the Str.

N must be an int num in the range [0, Str.size].

Example:

stdout.print_line('foobar'.drop_front(2).repr)  # => "obar"

Str.drop_back(N)

Str.drop_back makes a str dropping the last N runes of the Str.

N must be an int num in the range [0, Str.size].

Example:

stdout.print_line('foobar'.drop_back(2).repr)  # => "foob"

Str.search_slice(Min_ind Slice)

Str.search_slice searches the Slice in the Str.

Preconditions:

• Min_rune_ind must be an int num in the range [0, Str.size]

• Slice must be a str

Str.search_slice tries to find the smallest Ind which is >= Min_ind, such that Str.slice(Ind Slice.size) is equal to Slice.

If such an Ind is found, Str.search_slice returns a vec [Ind].

If not found, Str.search_slice returns an empty vec [].

Example:

:attempt_search <- {(:Str :Min_ind :Slice)
  Str.search_slice(Min_ind Slice).with_just_or(
    {(:Ind) stdout.print_line('found at: {}'.format(Ind.repr)) }
    { stdout.print_line('not found') }
  )
}
attempt_search('foofoo' 0 'oo')  # => found at: 1
attempt_search('foofoo' 1 'oo')  # => found at: 1
attempt_search('foofoo' 2 'oo')  # => found at: 4
attempt_search('foofoo' 3 'oo')  # => found at: 4
attempt_search('foofoo' 4 'oo')  # => found at: 4
attempt_search('foofoo' 5 'oo')  # => not found
attempt_search('foofoo' 6 'oo')  # => not found

Str.have_prefix?(Prefix)

Str.have_prefix? returns whether the Str has the slice Prefix at the front.

Prefix must be a str.

If Str.slice(0 Prefix.size) is equal to Prefix, Str.have_prefix? returns true. If not, Str.have_prefix? returns false.

Str.have_suffix?(Suffix)

Str.have_suffix? returns whether the Str has the slice Suffix at the back.

Suffix must be a str.

If Str.slice(Str.size - Suffix.size Str.size) is equal to Suffix, Str.have_suffix? returns true. If not, Str.have_suffix? returns false.

Str.have_slice?(Slice)

Str.have_slice? returns whether the Str has the Slice.

Slice must be a str.

If there is an Ind such that Str.slice(Ind Ind+Slice.size) is equal to Slice, Str.have_slice? returns true. If not, Str.have_slice? returns false.

Str.trim

Str.trim returns a slice of the Str trimming space-like characters from the front and the back.

Str.trim returns the longest slice of the Str which does not start with the Rune smaller than or equal to 32 (whitespace character), and does not end with the Rune smaller than or equal to 32.

Exaample:

stdout.print_line(" \t\r\nfoobar\n\r\t ".trim.repr) # => "foobar"
stdout.print_line(" \t\r\n\n\r\t ".trim.repr)       # => ""

Str.ascii_upcase

`ascii_upcase` converts runes of ASCII lowercase letters (from U+0061='a' to U+007A='z') in `Str` to the corresponding ASCII uppercase letters (from U+0041='A' to U+005A='Z').

`ascii_upcase` does not change runes except for ASCII lowercase letters.

Example:

stdout.print_line('Azkaban'.ascii_upcase.repr) # => "AZKABAN"
stdout.print_line('+-*/%<>'.ascii_upcase.repr) # => "+-*/%<>"
stdout.print_line('Товарищ'.ascii_upcase.repr) # => "Товарищ"

Str.ascii_downcase

`ascii_downcase` converts runes of ASCII uppercase letters (from U+0041='A' to U+005A='Z') in `Str` to the corresponding ASCII lowercase letters (from U+0061='a' to U+007A='z').

`ascii_downcase` does not change runes except for ASCII uppercase letters.

Example:

stdout.print_line('aZKABAN'.ascii_downcase.repr)  # => "azkaban"
stdout.print_line('+-*/%<>'.ascii_downcase.repr)  # => "+-*/%<>"
stdout.print_line('Товарищ'.ascii_downcase.repr)  # => "Товарищ"

Str.format(... Args) / Str.format($config)

Str.format generates a str which is formatted using `Str` as a template.

Str.format has two overloads.

Overload: Str.format(... Args)

When called with variadic args `Args`, Str.format uses each element of `Args` as a positional argument.

Preconditions:

• `Str` must be a str which suffices the syntax described below.

• Each element of `Args` must have `show` method.

Overload: Str.format($config)

When called with $config fun, Str.format uses $config as a config fun.

Preconditions:

• `Str` must be a str which suffices the syntax described below.

• $config must be a fun which takes a format_conf val.

The format of the template str

A template str can contain placeholders delimited by braces "{" and "}". Str.format invokes .show(...[$show_config]) method of the arg corresponding to each placeholder, and emplaces the result str in the placeholder.

There are following variants of placeholders.

• "{}": takes a positional argument, with an empty str "" as the spec.

• "{%xxx}": takes a positional argument, with the spec "xxx".

• "{Foo}": takes a named argument with the name "Foo", with an empty str "" as the spec.

• "{Foo%xxx}": takes a named argument with the name "Foo", with the spec "xxx".

The name str must not contain "{", "}" and "%".

The spec str is passed to Show_conf.spec(Spec) method. The spec str must not contain "{" or "}".

If you want to include literal "{" and "}" in the template str, escape them as "{{" and "}}".

Examples

stdout.print_line('{} == 0x{%04x}'.format(42 42))
# => 42 == 0x002a

stdout.print_line('{}: message: {}'.format('WARN' 'something went wrong'))
# => WARN: message: something went wrong

With locale:

:LOCALE.require_from('kink/')

:Str <- 'Id: {%04d}, Name: {}, Elevation: {%,d} meters'.format{(:C)
  C.locale(LOCALE.for('da-DK'))
  C.arg(12)
  C.arg('Mount Fuji')
  C.arg(3776.24)
}
stdout.print_line(Str)
# => Id: 0012, Name: Mount Fuji, Elevation: 3.776,24 meters

Using named args:

:LOCALE.require_from('kink/')

:Str <- 'Id: {Id%04d}, Name: {Name}, Elevation: {Elevation%,d} meters'.format{(:C)
  C.locale(LOCALE.for('da-DK'))
  C.named_arg('Id' 12)
  C.named_arg('Name' 'Mount Fuji')
  C.named_arg('Elevation' 3776.24)
}
stdout.print_line(Str)
# => Id: 0012, Name: Mount Fuji, Elevation: 3.776,24 meters

Str.op_mul(N)

Str.op_mul makes a str repeating the Str N times.

N must be a nonnegative int num.

Example:

stdout.print_line(('foo' * 0).repr) # => ""
stdout.print_line(('foo' * 1).repr) # => "foo"
stdout.print_line(('foo' * 2).repr) # => "foofoo"
stdout.print_line(('foo' * 3).repr) # => "foofoofoo"

Str1.op_eq(Str2)

`op_eq` returns whether two strs contains the same sequence of runes.

Precondition:

• `Str1` and `Str2` must be strs.

Example:

stdout.print_line(('foo' == 'foo').repr)  # => true
stdout.print_line(('foo' != 'foo').repr)  # => false

stdout.print_line(('foo' == 'FOO').repr)  # => false
stdout.print_line(('foo' != 'FOO').repr)  # => true

Str1.op_lt(Str2)

`op_lt` returns compares the runes of the strs lexicographically, then returns whether `Str1` is less than `Str2`.

Precondition:

• `Str1` and `Str2` must be strs.

Example:

:compare <- {(:Str1 :Str2)
  [:Lt? :Le? :Gt? :Ge?] = [
    Str1 < Str2
    Str1 <= Str2
    Str1 > Str2
    Str1 >= Str2
  ]
  stdout.print_line(
    'Lt?={} Le?={} Gt?={} Ge?={}'.format(Lt?.repr Le?.repr Gt?.repr Ge?.repr))
}

compare('foo' 'foo')  # => Lt?=false Le?=true Gt?=false Ge?=true
compare('foo' 'fooo') # => Lt?=true Le?=true Gt?=false Ge?=false
compare('foo' 'fo')   # => Lt?=false Le?=false Gt?=true Ge?=true

Note that the result of comparison may differ from java.lang.String.compareTo. The reason is that the Java method compares strings by UTF-16 units.

:JAVA.require_from('kink/javahost/')
:X <- "\x{00ffff}"
:Y <- "\x{010302}"
stdout.print_line((X < Y).repr)  # => true
stdout.print_line(
  (JAVA.string(X).call_method('compareTo' [JAVA.string(Y)]).to_kink_num < 0).repr
)  # => false

Str.show(...[$config={}])

Str.show returns the Str itself.

Str.show can take an optional parameter $config, but it is never used. This parameter exists in order to meet the expectation by `format` method.

Example:

stdout.print_line('xyz'.show)
# Output:
#   xyz

stdout.print_line('xyz'.show{})
# Output:
#   xyz

stdout.print_line("foo\nbar".show)
# Output:
#   foo
#   bar

Str.repr

Str.repr returns the str representation of the Str for debugging, such as "xyz" and "foo\nbar".

Example:

stdout.print_line('xyz'.repr)       # => "xyz"
stdout.print_line("foo\nbar".repr)  # => "foo\nbar"

3.21.2. type format_conf

A format_conf is a conf val of Str.format.

Format_conf.arg(Pos_arg)

`arg` method adds a positional arg.

Precondition:

• `Pos_arg` must support .show(...[$show_config]) method

The number of invocations of `arg` method must be equal to the unnamed placeholders.

Format_conf.named_arg(Name Arg)

`named_arg` method adds a named arg.

Preconditions:

• `Name` must be a nonempty str which does not contain "{", "}", or "%"

• `Arg` must support .show(...[$show_config]) method

• The set of Name1, Name2 ,,, must be a superset of the names of the named arguments in the Template

All the names of the named args in the template str must be specified by `named_arg` method.

It is permitted to pass `Name` which is not the name of any named arg in the template str. For example:

stdout.print_line('X={X}, Y={Y}'.format{(:C)
    C.named_arg('X' 10)
    C.named_arg('Y' 20)
    C.named_arg('Z' 30) # Z is not in the template str, but it is OK
  }
)
# => X=10, Y=20

Format_conf.locale(Locale)

`locale` method specifies the locale.

Precondition:

• Locale must be a locale

3.21.3. type show_conf

A show_conf is a conf val type of .show(...[$show_config]) methods.

`show` method is expected to return a str which represents the receiver val. In contrast to `repr method, which is used for debugging, the result of `show` method is intended to be used in UI messages.

Usually, `show` methods are called from Str.format. See Str.format for details.

Example usage:

:LOCALE.require_from('kink/')
:Shown <- 3776.24.show{(:S)
  S.locale(LOCALE.for('da-DK'))
  S.spec(',d')
}
stdout.print_line(Shown.repr) # => "3.776,24"

An implementation of show_conf type can also implement extra methods such as Num_show_conf.radix and .pad_zero.

For example:

:Shown <- 255.show{(:S)
  S.radix(16)
  S.pad_zero(4)
}
stdout.print_line(Shown.repr) # => "00ff"

Show_conf.locale(Locale_name)

`locale` method specifies the locale which is used to generate the result of `show` method.

Precondition:

• `Locale_name` must be a locale.

Show_conf.spec(Spec)

`spec` method specifies how the val is converted to a str.

Precondition:

• `Spec` must be a str.

The syntax of `Spec` str varies among `show` method implementations.

3.21.4. STR.is?(Val)

STR.is? returns whether the Val is a str val.

3.21.5. STR.from_runes(Runes)

`from_runes` makes a str which contains the runes.

Precondition:

• `Runes` must be a sequence which support `each` method, such as vec or iter.

• Elements of `Runes` must be int nums in the range [0x000000, 0x10ffff].

Example using vec:

:STR.require_from('kink/')
:Str <- STR.from_runes([120 121 122])
stdout.print_line(Str.repr) # => "xyz"

Example using iter:

:ITER.require_from('kink/iter/')
:STR.require_from('kink/')
:Str <- STR.from_runes(ITER.of(120 121 122))
stdout.print_line(Str.repr) # => "xyz"

3.21.6. STR.default_newline

STR.default_newline returns the line separator str default to the runtime.

The result is either "\r\n" or "\n".