入出力

 cf. 12 入出力 – IO – Elixir

入出力モジュール

標準入出力を使って出力するには IO.puts、入力するには IO.gets を使う。

iex(1)> IO.puts "hello world"
hello world
:ok
iex(2)> IO.gets "yes or no? "
yes or no? yes
"yes\n"

IO.puts の引数に :stderr を渡すと、標準エラー出力に出力する。

iex(3)> IO.puts :stderr, "hello world"
hello world
:ok

ファイルモジュール

File モジュールを使って、ファイルの読み書きができる。

iex(4)> {:ok, file} = File.open "hello", [:write]
{:ok, #PID<0.85.0>}
iex(5)> IO.binwrite file, "world"
:ok
iex(6)> File.close file
:ok
iex(7)> File.read "hello"
{:ok, "world"}

ファイルは、デフォルトではバイナリモードで開かれる。:utf8 を指定することで UTF-8 エンコーディングで開くこともできる。
File モジュールに関数には ! (バンと読む)のついた関数とついていない関数がある。違いはエラーを起こすかどうかだ。

iex(8)> File.read "hello"
{:ok, "world"}
iex(9)> File.read! "hello"
"world"
iex(10)> File.read "unknown"
{:error, :enoent}
iex(11)> File.read! "unknown"
** (File.Error) could not read file "unknown": no such file or directory
    (elixir) lib/file.ex:244: File.read!/1

存在するファイル hello を読み込むときにはどちらも同じだけど、存在しないファイル unknown を読み込もうとしたとき、File.read は単に {:error, :enoent} というタプルを返しているだけなのに対して、File.read! はエラーを発生させている。

パスモジュール

Path モジュールは、パス文字列の操作に使う。

iex(11)> Path.join("foo", "bar")
"foo/bar"
iex(12)> Path.expand("hello")
"c:/Users/takatoh/Documents/w/learning-elixir/GettingStarted/hello"

デーモンとして動かすSinatraアプリにユーザーのインストールしたRubyを使わせる

以前作った Sinatra アプリ(フォトビューワー)をデーモンとして動かそうとしてハマった記録。
Sinatra アプリをデーモン化したことは前にもやったことがあるので、基本的にはその時のエントリを見ながらやったんだけど、一つだけ、ハマりどころがあった。それはアプリが Ruby 2.0 以降(だっけ?)にサポートしているキーワード引数を使って書いてあるのに対して、システムにインストールされているのは Ruby 1.9.3 だってこと。ユーザーは rvm でインストールした 2.3.0 を使っているのでテスト中は動くけど、いざ本番になってみるとシステムの 1.9.3 が使われるので動かない。
どうにかしてデーモンにも rvm でインストールした 2.3.0 を使わせたい。
探し方が悪いのか、ググっても情報が出てこない。結局解決策を見つけたのは、自分のエントリだった。

つまり、起動スクリプトで GEM_PATH と GEM_HOME に rvm のパスを設定して export すればいいようだ。書いた起動スクリプトがこれ:

#!/bin/sh

PATH=/home/potov/.rvm/rubies/ruby-2.3.0/bin:/home/potov/.rvm/gems/ruby-2.3.0/bin:/sbin:/bin:/usr/bin
GEM_PATH=/home/potov/.rvm/gems/ruby-2.3.0
GEM_HOME=/home/potov/.rvm/gems/ruby-2.3.0
export PATH
export GEM_PATH
export GEM_HOME

POTOV_ROOT=/home/potov/potov

case "$1" in
start)
cd ${POTOV_ROOT}
unicorn -c unicorn.conf -D
;;
stop)
PID=`cat ${POTOV_ROOT}/unicorn.pid`
kill -QUIT ${PID}
;;
*)
echo "Usage: potov {start|stop}"
exit 1
;;
esac

exit 0

当然 PATH も rvm の Ruby のパスを設定している。
ともあれ、これで無事起動するようになった。