Stringモジュールで遊んでみたシリーズ⑧ -String.split_at ~ String.to_charlist の紹介

こんにちは！
プログラミング未経験文系出身、Elixirの国に迷い込んだ？！見習いアルケミストのaliceと申します。
今回はStringモジュールについて学んだことをまとめます。

# 目次
1.[Stringモジュールで遊んでみたシリーズ① -String.at ~ String.chunk の紹介](https://qiita.com/Alicesky2127/items/47fffc38711d7369beee)
2.[Stringモジュールで遊んでみたシリーズ② -String.codepoints ~ String.ends_with? の紹介](https://qiita.com/Alicesky2127/items/5db34c69993d35b8f3a7)
3.[Stringモジュールで遊んでみたシリーズ③ -String.equivalent? ~ String.last の紹介](https://qiita.com/Alicesky2127/items/37aa8e62e8e1d5fef3b6)
4.[Stringモジュールで遊んでみたシリーズ④ -String.length ~ String.next_grapheme の紹介](https://qiita.com/Alicesky2127/items/e3fa2092a67cb9f6ec9c)
5.[Stringモジュールで遊んでみたシリーズ⑤ -String.next_grapheme_size ~ String.printable? の紹介](https://qiita.com/Alicesky2127/items/a315148e966c9f103a7c)
6.[Stringモジュールで遊んでみたシリーズ⑥ -String.replace ~ String.replace_suffix の紹介](https://qiita.com/Alicesky2127/items/94a77afe270587ed21a9)
7.[Stringモジュールで遊んでみたシリーズ⑦ -String.replace_trailing ~ String.split の紹介](https://qiita.com/Alicesky2127/items/1a8e9c92fa758d0b1337)
8.Stringモジュールで遊んでみたシリーズ⑧ -String.split_at ~ String.to_charlist の紹介(本記事)
9.[Stringモジュールで遊んでみたシリーズ⑨ -String.to_existing_atom ~ String.trim の紹介](https://qiita.com/Alicesky2127/items/9bf2b1effc3b68819ac2)
10.[Stringモジュールで遊んでみたシリーズ10 -String.trim_leading ~ String.valid? の紹介](https://qiita.com/Alicesky2127/items/b8310a3f5fc5b040ca78)

# 目的 
Stringモジュールに含まれる関数を触って機能を理解したい

https://hexdocs.pm/elixir/String.html

## 実行環境
Windows 11 ＋ WSL2 ＋ Ubuntu 22.04
Elixir v1.17.3
Erlang v27.0



# String.split_atとは
`String.split_at(string, position)`は書記素ベースで、`string`に対して`position`の位置で分割したタプルを返します。

## 例
```diff_elixir:iex
String.split_at("いろはにほへと", 5)
```
```
{"いろはにほ", "へと"}
```

`position`が`string`の長さより大きい場合。
```diff_elixir:iex
String.split_at("いろはにほへと", 7)
```
```
{"いろはにほへと", ""}
```

`position`が負の数の場合。
`string`の末尾からインデックスを数えます
```diff_elixir:iex
String.split_at("いろはにほへと", -1)
```
```
{"いろはにほへ", "と"}
```

`position`が負の数かつ`string`の長さより大きい場合。
```diff_elixir:iex
String.split_at("いろはにほへと", -7)
```
```
{"", "いろはにほへと"}
```


# String.splitterとは
`String.splitter(string, pattern, options \\ [])`は`pattern`に応じて文字列を分割する列挙型(=enumreable)を返します。
この関数にはString.splitと異なり正規表現のサポートがありません。

正規表現のサポートについては、`String.split`もご参照ください↓

https://qiita.com/Alicesky2127/items/400e6c928b791609b6d5#stringsplit3%E3%81%ABregexsplit3%E3%81%AEoption%E3%82%92%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%82%8B




## 例
カンマを区切り文字として部分文字列に分割。
分割されたうち先頭の4要素だけを返します。
```diff_elixir:iex
String.splitter("1,2,3,4,5,6,7,8,9", ",") |> Enum.take(4)
```
```
["1", "2", "3", "4"]
```

半角スペースおよびカンマを区切り文字として部分文字列に分割。
分割されたうち先頭の4要素だけを返します。
```diff_elixir:iex
String.splitter("1,2 3,4 5,6 7,8,...,99999", [" ", ","]) |> Enum.take(4)
```
```
["1", "2", "3", "4"]
```


```diff_elixir:iex
String.splitter("1,2,3,4,5,6,7,8,9", ",") |> Enum.take(4)
```
```
["1", "2", "3", "4"]
```



# String.starts_with?とは
`String.starts_with?(string, prefix)`は`string`が`prefix`で始まるか否かをチェックします。

## 例

```diff_elixir:iex
String.starts_with?("いろはにほへと", "いろ")
```
```
true
```

`prefix`を複数指定する場合。
`string`がリスト内のいずれかの`prefix`で始まれば`true`を返します。
```diff_elixir:iex
String.starts_with?("いろはにほへと", ["い","ろ"])
```
```
true
```

`prefix = ""`の場合。
常に`true`を返します。
```diff_elixir:iex
String.starts_with?("いろはにほへと", "")
```
```
true
```

`prefix = []`の場合。
常に`false`を返します。
```diff_elixir:iex
String.starts_with?("いろはにほへと", [])
```
```
false
```

# String.to_atomとは
`String.to_atom(string)`は`string`をatomに変換します。

:::note alert
この関数はアトムを動的に作成します。
アトムは自身の名前が値になるもので、ガベージコレクションされません。
したがって`string`にソケットから受信した入力やWebリクエスト中の入力など信頼できない値を渡してはいけません。
:::

※もし動的な値を`string`に渡してしまうと、名前と値の異なるアトムが大量に作られてErlang VMのアトムの許容範囲外に出てしまうリスクがあると理解しています[^1]


## 例
```diff_elixir:iex
String.to_atom("my_atom")
```
```
:my_atom
```


# String.to_charlistとは
`String.to_charlist(string)`は`string`を文字リストに変換します。
## 例
```diff_elixir:iex
String.to_charlist("いろはにほへと")
```

※下記`12356`はUnicodeのコードポイントU+3044の10進数表記です
```
[12356, 12429, 12399, 12395, 12411, 12408, 12392]
```


```diff_elixir:iex
String.to_charlist("foo")
```
```
~c"foo"
```

### 補足1
~cは文字列リストを指すシギルです[^2]

### 補足2
具体的には、この関数は UTF-8 でエンコードされたバイナリを受け取り、そのコードポイントのリストを返します。

#### 例
下記の`Raw representation`部分から、整数コードポイントのリストを返していることが確認できます

```diff_elixir:iex
i ~c"foo"
```

```
Term
  ~c"foo"
Data type
  List
Description
  This is a list of integers that is printed using the `~c` sigil syntax,
  defined by the `Kernel.sigil_c/2` macro, because all the integers in it
  represent printable ASCII characters. Conventionally, a list of Unicode
  code points is known as a charlist and a list of ASCII characters is a
  subset of it.
Raw representation
  [102, 111, 111]
Reference modules
  List
Implemented protocols
  Collectable, Enumerable, IEx.Info, Inspect, List.Chars, String.Chars
```


# ～Elixirの国のご案内～
↓Elixirって何ぞや？と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます:laughing::sparkles::sparkles:

https://qiita.com/piacerex/items/09876caa1e17169ec5e1

↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ！私もエンジニア未経験から学習中です。

https://elixir-lang.info/topics/entry_column


↓[We Are The Alchemists, my friends!:bouquet:](https://qiita.com/torifukukaiou/items/6bcd5bbb80df9e594e9e "Awesome-san's Awesome article")[^10]
Elixirコミュニティは本当に優しくて温かい人たちばかり！
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。[^11]


https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian

[^1]:https://www.erlang.org/doc/system/memory.html#system-limits

[^2]:https://hexdocs.pm/elixir/sigils.html

[^10]: @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。


[^11]: @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中！