6.23. kink/STR¶
6.23.1. str型¶
str は有限長の不変なUnicodeコードポイントの文字列である。
Unicodeコードポイントについては右記を参照: https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-3/#G22700
サロゲートコードポイント
strは対にならないサロゲートコードポイントを含むことができる。
上位サロゲートコードポイントに下位サロゲートコードポイントが後続した場合、UTF-16にしたがって単一のコードポイントに統合される。
:STR.require_from('kink/')
:S1 <- STR.of(0xd800)
stdout.print_line(S1.codepoints.repr) # => [55296]
:S2 <- STR.of(0xd800 0xdc00)
stdout.print_line(S2.codepoints.repr) # => [65536]
6.23.1.1. Str.codepoints¶
codepoints は Str のコードポイントを含む vec を戻す。
例
stdout.print_line('xyz'.codepoints.repr) # => [120 121 122]
6.23.1.2. Str.size¶
sizeはStrのコードポイントの数を整数のnumとして戻す。
6.23.1.3. Str.any?¶
any?はStrが1個以上のコードポイントを含んでいるかどうかを戻す。
6.23.1.4. Str.get(Codepoint_ind)¶
getはCodepoint_indの位置のコードポイントを戻す。
結果はコードポイントを表す整数のnumだ。
事前条件
Codepoint_indは、 [0, Str.size - 1] の範囲に含まれる整数のnumでなければならない。
例
stdout.print_line('xyz'.get(0).repr) # => 120
6.23.1.5. Str.slice(From To)¶
sliceは、Strのスライスを作ってstr値として戻す。
スライスは、[From, To)の範囲のコードポイントからなる。結果のstrは、(To - From)個のコードポイントを持つ。
事前条件
FromとToは整数のnum値でなければならない。
0 <= From <= To <= Str.size
例
:Str <- 'foobar'
:Slice <- Str.slice(1 4)
stdout.print_line(Slice.repr) # => "oob"
6.23.1.6. Str.take_front(N)¶
take_frontはStrの最初のN個のコードポイントを含むstrを戻す。
事前条件
Nは[0, Str.size]の範囲に含まれる整数のnumでなければならない。
例
stdout.print_line('foobar'.take_front(2).repr) # => "fo"
6.23.1.7. Str.take_back(N)¶
take_backはStrの最後のN個のコードポイントを含むstrを戻す。
事前条件
Nは[0, Str.size]の範囲に含まれる整数のnumでなければならない。
例
stdout.print_line('foobar'.take_back(2).repr) # => "ar"
6.23.1.8. Str.drop_front(N)¶
drop_frontはStrから最初のN個のコードポイントを除いたstrを戻す。
事前条件
Nは[0, Str.size]の範囲に含まれる整数のnumでなければならない。
例
stdout.print_line('foobar'.drop_front(2).repr) # => "obar"
6.23.1.9. Str.drop_back(N)¶
drop_backはStrの最後のN個のコードポイントを除いたstrを戻す。
事前条件
Nは[0, Str.size]の範囲に含まれる整数のnumでなければならない。
例
stdout.print_line('foobar'.drop_back(2).repr) # => "foob"
6.23.1.10. Str.search_slice(Slice Min_pos ...[$config={}])¶
search_sliceはStrの中でスライスを探す。探索をコードポイントの添字Min_posから始めて、見つかったスライスが始まるコードポイントの添字であるPosを出力する。
コンフィグメソッド:
• C.on_success($success): default = VAL.identity.
• C.on_error($error): default = 例外を投げる関数
search_sliceは、 Pos >= Min_pos と Str.slice(Pos Slice.size) == Slice を満たす最も小さいPosを探す。もしそのようなPosが見つかれば、search_sliceは$successを、Posを引数として末尾呼び出しする。もし見つからなければ、search_sliceは$errorを引数なしで末尾呼び出しする。
事前条件
Slice は str 型でなければならない。
Min_posは [0, Str.size] の範囲の整数のnumでなければならない。
$successは整数のnumを取る関数でなければならない。
$errorはサンクでなければならない。
例
stdout.print_line('foofoo'.search_slice('oo' 0).repr) # => 1
stdout.print_line('foofoo'.search_slice('oo' 1).repr) # => 1
stdout.print_line('foofoo'.search_slice('oo' 2).repr) # => 4
'foofoo'.search_slice('oo' 5)
# Output:
# -- main exception
# ,,,
# Str.search_slice(Slice Min_pos ...[$config]): slice not found
例
:attempt_search <- {(:Str :Min_pos :Slice)
Str.search_slice(Slice Min_pos){(:C)
C.on_success{(:Pos)
stdout.print_line('found at: {}'.format(Pos.repr))
}
C.on_error{
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
6.23.1.11. Str.have_prefix?(Prefix)¶
have_prefix?はStrの先頭がPrefixかどうかを戻す。
Str.take_front(Prefix.size) がPrefixに等しいとき、have_prefix?はtrueを戻す。そうでなければ、have_prefix?はfalseを戻す。
事前条件
Prefix は str 型でなければならない。
6.23.1.12. Str.have_suffix?(Suffix)¶
have_suffix?はStrの末尾がSuffixかどうかを戻す。
Str.take_back(Suffix.size) がSuffixに等しいとき、have_suffix?はtrueを戻す。そうでなければ、have_suffix?はfalseを戻す。
事前条件
Suffix は str 型でなければならない。
6.23.1.13. Str.have_slice?(Slice)¶
have_slice?はStrがSliceをスライスとして持っているかどうかを戻す。
もし Str.slice(Ind Ind + Slice.size) がSliceと等しいようなIndがあれば、have_slice?はtrueを戻す。なければ、have_slice?はfalseを戻す。
事前条件
Slice は str 型でなければならない。
6.23.1.14. Str.trim¶
trimはStrの先頭と末尾から空白類の文字を取り除いたスライスを戻す。
trimはStrのスライスのうち、空白類の文字で始まらず、空白類の文字で終わらない最長のスライスを戻す。
空白類の文字は、[U+0000, U+0020]の範囲内のコードポイント、あるいはU+007fである。
例
stdout.print_line(" \t\r\nfoobar\n\r\t ".trim.repr) # => "foobar"
stdout.print_line(" \t\r\n\n\r\t ".trim.repr) # => ""
6.23.1.15. Str.trim_front¶
trim_frontはStrの先頭から空白類の文字を取り除いたスライスを戻す。
trim_frontはStrのスライスのうち、空白類の文字で始まらない最長のスライスを戻す。
空白類の文字の定義は trim を見よ。
例
stdout.print_line(" \t\r\nfoobar\n\r\t ".trim_front.repr) # => "foobar\n\r\t "
stdout.print_line(" \t\r\n\n\r\t ".trim_front.repr) # => ""
6.23.1.16. Str.trim_back¶
trim_backはStrの末尾から空白類の文字を取り除いたスライスを戻す。
trim_backはStrのスライスのうち、空白類の文字で終わらない最長のスライスを戻す。
空白類の文字の定義は trim を見よ。
例
stdout.print_line(" \t\r\nfoobar\n\r\t ".trim_back.repr) # => " \t\r\nfoobar"
stdout.print_line(" \t\r\n\n\r\t ".trim_back.repr) # => ""
6.23.1.17. Str.ascii_upcase¶
ascii_upcaseは、Str中のASCII小文字のコードポイント(U+0061='a' から U+007A='z')を、対応するASCII大文字(U+0041='A' から U+005A='Z')に変換する。
ascii_upcaseは、ASCII小文字以外のコードポイントを変換しない。
例
stdout.print_line('Azkaban'.ascii_upcase.repr) # => "AZKABAN"
stdout.print_line('+-*/%<>'.ascii_upcase.repr) # => "+-*/%<>"
stdout.print_line('Товарищ'.ascii_upcase.repr) # => "Товарищ"
6.23.1.18. Str.ascii_downcase¶
ascii_downcaseは、Str中のASCII大文字のコードポイント(U+0041='A' から U+005A='Z')を、対応するASCII小文字(U+0061='a' から U+007A='z')に変換する。
ascii_downcaseはASCII大文字以外のコードポイントを変換しない。
例
stdout.print_line('aZKABAN'.ascii_downcase.repr) # => "azkaban"
stdout.print_line('+-*/%<>'.ascii_downcase.repr) # => "+-*/%<>"
stdout.print_line('Товарищ'.ascii_downcase.repr) # => "Товарищ"
6.23.1.19. Str.well_formed?¶
well_formed?は、Strのすべてのコードポイントがunicode scalar value であるかどうかを戻す。
言い換えると、well_formed?は、対にならないサロゲートコードポイントをStrが含まないことを検証する。
6.23.1.20. Str.format(... Args) / Str.format($config)¶
formatは、Strをテンプレートとしてstrを生成する。
format にはふたつのオーバーロードがある。
オーバーロード: Str.format(... Args)
可変長の引数Argsが渡されたとき、formatはArgsの各要素を位置引数として使う。
事前条件:
• Strは下記の文法を満たすstrでなければならない。
• Argsの各要素はshowメソッドを持っていなければならない。
オーバーロード: Str.format($config)
$configが渡されたとき、formatは$configをコンフィグ関数として使う。
事前条件:
• Strは下記の文法を満たすstrでなければならない。
• $configはformat_configを引数として取る関数でなければならない。
テンプレート文字列の書式
テンプレート文字列には、波括弧 "{" と "}" で区切られたプレースホルダを含められる。formatはプレースホルダに対応する引数について、 .show(...[$config]) メソッドを呼び、その結果の文字列をプレースホルダの場所に埋め込む。
プレースホルダには次の変種がある。
• "{}": 位置引数を取り、空文字列 "" を指示子とする。
• "{%xxx}": 位置引数を取り、 "xxx" を指示子とする。
• "{Foo}": "Foo" という名前の名前引数を取り、空文字列 "" を指示子とする。
• "{Foo%xxx}": "Foo" という名前の名前引数を取り、 "xxx" を指示子とする。
名前には "{", "}", "%" が含められない。
指示子はShow_config.spec(Spec)メソッドに渡される。指示子には "{", "}" が含められない。
テンプレート文字列に "{" と "}" を含めたい場合、 "{{", "}}" としてエスケープする。
例
stdout.print_line('{} == 0x{%04x}'.format(42 42))
# => 42 == 0x002a
stdout.print_line('{}: message: {}'.format('WARN' 'something went wrong'))
# => WARN: message: something went wrong
ロケールを指定:
: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
名前引数を使う:
: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
6.23.1.21. Str1 + Str2¶
+ 演算子、つまりop_addメソッドは、Str1のコードポイント列を前に、Str2のコードポイント列を後ろに配した文字列を戻す。
事前条件
Str2 は str 型でなければならない
例
:Str <- 'foo' + 'bar'
stdout.print_line(Str.repr) # => "foobar"
6.23.1.22. Str * N¶
* 演算子、つまりop_mulメソッドは、StrをN回繰り返した文字列を戻す。
事前条件
Nは非負整数のnumでなければならない。
例
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"
6.23.1.23. Str1 == Str2¶
== 演算子、つまりop_eqメソッドは、ふたつの文字列が同じコードポイントの列から成っているかどうかを戻す。
事前条件
Str1とStr2はstr型でなければならない。
例
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
6.23.1.24. Str1 <= Str2¶
<= 演算子、つまりop_leメソッドは、ふたつの文字列のコードポイントを辞書順で比較し、Str1がStr2以下かどうかを戻す。比較はUnicodeのコードポイントの大小関係に従って、先頭から末尾にかけて行われる。
比較の結果は java.lang.String.compareTo と異なり得ることに注意しよう。これは、String.compareToが文字列の比較を16ビットのコードユニットを元に行うためだ。
事前条件
Str2はstr型でなければならない。
例
stdout.print_line(('fo' <= 'foo').repr) # => true
stdout.print_line(('foo' <= 'foo').repr) # => true
stdout.print_line(('fooo' <= 'foo').repr) # => false
stdout.print_line(("\x{ffff}" <= "\x{10000}").repr) # => true
6.23.1.25. Str.show(...[$config={}])¶
showはStr自体を戻す。
showは省略可能なパラメータ$configを取れるが、これが呼ばれることはない。
.showメソッドの一般的な契約については、この記事中の *.show(...[$config]) を見よ。
例
stdout.print_line('xyz'.show)
# Output:
# xyz
stdout.print_line('xyz'.show{})
# Output:
# xyz
stdout.print_line("foo\nbar".show)
# Output:
# foo
# bar
6.23.1.26. Str.repr¶
reprはStrのデバッグ用の文字列表現を戻す。
例
stdout.print_line('xyz'.repr) # => "xyz"
stdout.print_line("foo\nbar".repr) # => "foo\nbar"
6.23.2. format_config型¶
format_configはStr.formatのコンフィグ値である。
6.23.2.1. Format_config.arg(Pos_arg)¶
argメソッドは位置引数を追加する。
argメソッドの呼び出し回数は、名前のないプレースホルダの数と同じでなければならない。
事前条件
Pos_argは .show(...[$config]) メソッドを提供しなければならない。
6.23.2.2. Format_config.named_arg(Name Arg)¶
named_argメソッドは名前引数を追加する。
テンプレート文字列中で参照されない Name を渡しても構わない。
事前条件
Name は空でない str である必要がある。また、正規表現 [a-zA-Z_][a-zA-Z0-9_?]* に受け入れられる必要がある。
Arg は .show(...[$config]) メソッドを提供しなければならない。
Name1, Name2, ,,, の集合は、テンプレート中の名前引数の名前の集合の上位集合でなければならない。
例
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
6.23.2.3. Format_config.locale(Locale)¶
localeメソッドはロケールを指定する。Localeは各プレースホルダのshowメソッドに渡される。
事前条件
Locale は locale 型でなければならない。
6.23.3. *.show(...[$config={}]) メソッド¶
この節では、任意の型のshowメソッドについて一般的な契約を述べる。
showメソッドには、レシーバを表現する文字列を戻すことが期待される。reprメソッドがデバッグメッセージに使われるのに対して、showメソッドはUIメッセージに使われる。
通常、showメソッドはStr.formatから呼ばれる。
コンフィグメソッド
• C.locale(Locale): default = Locale.root
• C.spec(Spec): default = ''
Localeはlocale型でなければならない。showメソッドはロケールを用いて結果をローカライズできる。
Specはstr型でなければならない。showメソッドはこの指示子を用いて結果を調整できる。指示子の文法はshowメソッドの実装に依存するが、少なくともshowメソッドは空文字列 '' を指示子として受け取れなければならない。
例
: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"
showメソッドは上記以外のコンフィグメソッドも提供できる。たとえば、Num.showはradixとpad_zeroというコンフィグメソッドを提供する:
:Shown <- 255.show{(:S)
S.radix(16)
S.pad_zero(4)
}
stdout.print_line(Shown.repr) # => "00ff"
6.23.4. STR.is?(Val)¶
is?はValがstrであるかどうかを戻す。
6.23.5. STR.of(...Codepoints)¶
ofは引数で指定されたコードポイントを含むstrを戻す。
事前条件
すべての引数は [0x000000, 0x10ffff] の範囲の整数でなければならない。
例
:STR.require_from('kink/')
:Str <- STR.of(120 121 122)
stdout.print_line(Str.repr) # => "xyz"
6.23.6. STR.from_each(Codepoints)¶
from_eachは指定されたコードポイントを含むstrを戻す。
事前条件
Codepoints は each メソッドを提供する列でなければならない。たとえば vec や iter など。
Codepoints の要素は [0x000000, 0x10ffff] の範囲の整数でなければならない。
例
:STR.require_from('kink/')
:Str <- STR.from_each([120 121 122])
stdout.print_line(Str.repr) # => "xyz"
例
:ITER.require_from('kink/iter/')
:STR.require_from('kink/')
:Str <- STR.from_each(ITER.of(120 121 122))
stdout.print_line(Str.repr) # => "xyz"
6.23.7. STR.default_newline¶
default_newlineはランタイムのデフォルトの行区切りを戻す。
結果は str で、 "\r\n" か "\n" のどちらかである。