ElixirのFile関連の関数の多くはPath.t型の値を引数にとります。しかしながら、サンプルコード見ると全て"mix.exs"
のようになんの変哲もない普通の文字列でパスが表現されています。Path.t型とは一体何なのか気になります。
これからElixirを始める方にはこのサイトがおすすめです。
Elixirとコミュニティの雰囲気をゆるく味わいたい方は「先端ピアちゃん」さんの動画が超オススメです。
結論
- Path.tは、IO.chardataでした。
- IO.chardataは、String.tもしくはmaybe_improper_listとのことです。
File関連の関数
File関連の関数はFileモジュールにあります。例として、File.exists?/2を用いて、ファイルの存在の有無を確認することができます。ファイルへのパスはこのように文字列で渡すことがほとんどだと思います。
File.exists?("mix.exs")
File.exists?/2型はこのようになっています。
@spec exists?(Path.t(), [exists_option]) :: boolean() when exists_option: :raw
引数が文字列を表すString.tやbinary
ではなくPath.tとなっています。
Path.t型
ドキュメントのリンクをポチポチ押して確認するとPath.tがIO.chardataであることがわかります。さらに、IO.chardataはString.t() | maybe_improper_list(char() | chardata(), String.t() | [])
となっています。ざっくりとリストも渡せるということがわかりました。試してみます。
File.exists?("mix.exs")
File.exists?(["mix.exs"])
File.exists?(["mix", ".exs"])
File.exists?([?m, ?i, ?x, ?., ?e, ?x, ?s])
文字列や文字のリストにしても問題なくイゴきます。
ちゃんとしたリスト
ElixirのListは連結リストですので、[1, 2, 3]
というリストは[1 | [2 | [3]]]
のように頭部と尾部で成り立つリストが連結された構造をしています。
[1, 2, 3] = [1 | [2 | [3 | []]]]
文字リストもいろんな形で表現できます。
~c"mix.exs" = 'mix.exs'
~c"mix.exs" = [109, 105, 120, 46, 101, 120, 115]
~c"mix.exs" = [?m | [?i | [?x | [?. | [?e | [ ?x | [?s]]]]]]]
ちゃんとしていないリスト
通常Listはちゃんとした連結リストじゃないとダメなのですが、文字列連結の場合は変な構造のリストでも許されるようです。
Listがちゃんとしたものかどうかの判定はList.improper?/1でできます。正直言うと何がちゃんとしているのかよくわかりませんが、適当にListに文字や文字列を放り込むだけで連結された文字列のように扱ってくれるようです。
true = List.improper?(["mix" | ".exs"])
false = List.improper?(["mix" , ".exs"])
File.exists?(["mix" | ".exs"])
File.exists?(["mix", ".exs"])
余談ですが、文字列を何度も何度も生成すると効率が悪いのでListをビルダーとして活用するパターンが性能向上に有効との噂もあります。どの程度効果があるのかは知りません。