なんらかの入力に対して加工を施し,結果を出力する。形こそ違え ソフトウェアは原則としてそのような動きを持つ。Ruby で作成するコンソールプログラムでの入出力の方法をまとめる。
Rubyプログラム起動時に,そのプログラム名の後ろに指定された文字列は
単語ごとに区切られた配列として変数 ARGV
に入る。
./program.rb a "b c" d\ ef ghi
としたときのARGVは
ARGV[0] | ARGV[1] |
ARGV[2] | ARGV[3] |
---|---|---|---|
"a" | "b c" |
"d ef" | "ghi" |
となる。コマンドラインに指定した文字列の単語分解は シェルが規則に基づいて行なっている。
Rubyの場合はコマンドライン引数の個々をファイル名と見なし,
そのファイルの中味全体を結合したファイル入力を自動的に利用することができる。
これは変数
ARGF
を介して利用する。コマンドライン引数が何もない場合の
ARGF
は標準入力を指すオブジェクトとなる。
gets
メソッドを単体で使用することは
ARGF
からの読み込みを意味する。つまり,
while line=gets ... end
は,
while line=ARGF.gets ... end
と同じである。
Rubyプログラムに引数を何も与えない場合,単体で呼ぶ gets
メソッドは標準入力(STDIN; Standard Input)から読み込む。また,
単体で呼ぶ puts
,print
,printf
メソッドは,標準出力(STDOUT; Standard Output)に書き出す。
標準入力・標準出力は,とくに指定がなければ端末に結び付けられる。
つまり,入力はキーボード,出力は仮想端末の画面となる。
これらは,シェルの持つリダイレクションやパイプの機能で 入出力先をファイルや別のプログラムに切り替えることができる。
> file |
標準出力の行き先を file に切り替える |
< file |
標準入力の供給元を file に切り替える |
program1|
program2 |
program1の標準出力を program2 の標準入力につなぐ |
いくつか例を示す。
# program.rbの出力結果を outfile に ./program.rb > outfile # program.rbへの入力を infile から与える ./program.rb < infile # ls -l の出力結果を program.rb に送る ls -l | ./program.rb # infileの内容を program.rb に渡し,その出力を wc -l に渡し, # その出力を outfile に保存(下記いずれも同じ) < infile ./program.rb | wc -l > outfile ./program.rb < infile | wc -l > outfile ./program.rb < infile | > outfile wc -l < infile ./program.rb | > outfile wc -l
Rubyプログラムでは,起動時に引数を与えるとそれをファイルと見なして
単体の gets
はそこからデータを読む。起動時に引数を与えた
場合でも必ず標準入力を読みたい場合は,明示的に標準入力を表す
STDIN
(あるいはそれが代入された変数 $stdin
)から
gets
する。
while line = STDIN.gets
〜処理〜
end
標準出力は処理した結果を出力するためのものである。処理に失敗したとき などのエラーメッセージは,標準エラー出力に出すべきである。簡単な例を示す。
print "整数を2で割った数を求めます。偶数を入れてください: " n = gets.to_i if n % 2 == 0 then # 2で割った余りが0なら(偶数) printf("%d\n", n/2) # 結果のみ出力 else printf("%dは偶数ではありません。\n", n) # エラーメッセージ出力 end
このプログラムをファイルへの出力リダイレクション付きで起動し, 奇数を入力すると以下のようになる。
./div2.rb > outfile 5 cat outfile 整数を2で割った数を求めます。偶数を入れてください: 5は偶数ではありません。
原則として,結果出力は次の処理の入力として利用するかもしれないので,
対話メッセージなどを含めても無意味だし,エラーメッセージが
リダイレクトされてしまったら利用者には見えず警告の意味がなくなる。
利用者向けのメッセージなどは標準エラー出力に出す。Rubyでは
STDERR
(あるいは$stderr
) にて出力する。
上記の例を書き直したものを示す。
STDERR.print "整数を2で割った数を求めます。偶数を入れてください: " n = gets.to_i if n % 2 == 0 then # 2で割った余りが0なら(偶数) printf("%d\n", n/2) # 結果のみ出力 else STDERR.printf("%dは偶数ではありません。\n", n) # エラーメッセージ出力 end
これを同じリダイレクションで実行する。
./div2.rb > outfile 整数を2で割った数を求めます。偶数を入れてください: 5 5は偶数ではありません。 cat outfile # 何もない。結果がないことになるのでこれでよい。