スポンサーリンク

2015年9月19日

[Elixir]入出力の使い方を習得する

とある錬金術師の万能薬(Elixir)

Goal

Elixirの入出力を習得する。

Dev-Environment

OS: Windows8.1
Erlang: Eshell V6.4, OTP-Version 17.5
Elixir: v1.0.5

Wait a minute

今回は、IO、File、Pathモジュールについてやります。
簡単に使い方だけまとめて、必要になったらドキュメント見る程度です。

Index

IO, File and Path
|> IO
|> File
|> Path
|> Extra

IO

What is IO module

IOモジュールとはどんな機能を提供してくれるモジュールなのか?
IOのハンドリングを行うモジュールです。
標準入出力(:stdio)、標準エラー(:stderr)、ファイル、
他の入出力デバイスを読み書きするための基本となる機能を提供します。
多くの関数が、IOデバイスを必要とします。
引数の多くは、文字列、文字または文字列のリストを必要とします。
また、バイナリ、バイトまたはバイナリのリストである場合もあります。
それ以外のデータ型が与えられた場合、String.Charsプロトコルにより文字列に変換されるようです。
文字(列)を扱える型を寄越せってのが概ねのようですね。

Note:

IOデバイスはpidかアトム。
アトムならpid(プロセス)を登録したアトムである必要があります。
3つの例外
  • :standard_ioが与えられるとショートカットとして扱われる
  • :stdioは:standard_ioのショートカット
  • :stderrは:standard_errorのショートカット
便宜上、Elixirは、Erlangの:standard_ioと:standard_errorの ショートカットとして、:stdioと:stderrを提供します。

Example:

よく使うIO.puts/2もIOモジュールの関数ですね。
iex> IO.puts "hello world!!"
hello world!!
:ok
iex> IO.gets "yes of no?"
yes of no?yes
"yes\n"
詳しく知りたい方は、公式のドキュメントを読んで下さい。
Document: hexdocs - Elixir (v1.0.5) - IO

File

What is File module

Fileモジュールとはどんな機能を提供してくれるモジュールなのか?
そのままファイル関連を扱えるモジュールですが(笑)
Fileモジュールはファイルを操作するための機能を提供します。
関数は、UNIXのコマンド名であるものが多いです。
ファイルを扱う時、デフォルトではバイナリモードで開かれます。

Example:

defmodule FileSample do
  def write(path, write_data, opts) do
    file = open(path, opts)
    write_data(file, write_data)
    close(file)
  end

  def read(path) do
    File.read!(path)
  end

  defp open(path, opts) do
    case File.open(path, opts) do
      {:ok, file} -> file
      _ -> nil
    end
  end

  defp write_data(file, write_data) do
    IO.binwrite(file, write_data)
  end

  defp close(file) do
    File.close(file)
  end
end

Result:

ファイルに書き込みを行い、内容を確認します。
iex> FileSample.read "lib/tmp.txt"
""
iex> FileSample.write "lib/tmp.txt", "hogehoge", [:write]
:ok
iex> FileSample.read "lib/tmp.txt"
"hogehoge"
書き込んだファイルへ追記します。
iex> FileSample.write "lib/tmp.txt", "hugehuge", [:append]
:ok
iex> FileSample.read "lib/tmp.txt"
"hogehogehugehuge"
ファイルに関する大体の機能があるので、紹介できるのは極々一部です。
詳しく知りたい方は、公式のドキュメントを読んで下さい。
Document: hexdocs - Elixir (v1.0.5) - File

Path

What is Path module

Pathモジュールは、ファイル / ディレクトリのパスを操作できます。
また、パスから要素を取り出したりすることができます。
Pathで扱われる文字データは常にUTF-8でエンコードされます。

Example:

iex> Path.join("hoge", "huge")
"hoge/huge"
iex> Path.expand("./")
"path/to/current/directory"
iex> Path.expand("../")
"path/to/on/one"
iex(13)> Path.expand("~/")
"path/to/user"

Extra

まずこれを見て下さい。

Example:

iex> {:ok, file} = File.open "lib/tmp.txt", [:write]
{:ok, #PID<0.107.0>}
pidが返ってきていますね。これはどういうことを示しているのでしょうか?
Elixirでは、ファイルを開く度に新しいプロセスを生み出します。
つまり、ファイルへ何かを書き込む、もしくはファイルから何かを読み込むと言う処理は、
プロセスでメッセージをやり取りすることに等しいと言うことですね。
これはやろうと思えば、プロセスでファイルのやり取りが可能と言うことを示しています。
IOの関数では、IOデバイスが必要なことが多いと書きました。
先ほどの、ファイルはプロセスで扱える(扱っている)のを考えると、IOデバイスはプロセスであると予想がつきます。
IO.puts/2の定義を見てみます。

Quoted:

puts(device \\ group_leader(), item)
group_leader/0関数(?)とは何でしょう?
全ての入出力デバイスで,どのプロセスにも1つだけグループリーダーと呼ばれる特別なプロセスがあります。

Example:

iex> Process.group_leader
#PID<0.9.0>
つまりgroup_leader/0は、グループリーダのプロセスを取得する関数のようですね。
puts/2は、デフォルト値でプロセス(IOデバイス)を送っていたんですね。
IOデバイスもFileもプロセスで扱っていると言うことを覚えておけば、どこかで役に立つでしょう~

Speaking to oneself

結構長くなってしまった。
まぁいいや、後で見返した時に役に立つだろうし…

Bibliography

人気の投稿