オープンソースのオブジェクト指向プログラミング言語「Ruby」の文法を一から学ぶための入門連載。最新版の2.1に対応しています。今回は、Kernelモジュールに定義されている主な入出力メソッドとしてprint、puts、printf、gets、File/IOクラス、STDOUT、STDINの使い方、フィルターの作り方などを解説。
前回の「Rubyの例外とその捕捉――基本のbegin〜rescue〜endからensure、else、retry、後置rescueまで」では、オブジェクト指向言語ではポピュラーな仕組みである、例外とその捕捉といったトピックについて解説しました。例外をうまく扱うことで、ファイルが存在しない場合や、HTTP通信でデータを取得できない場合などに適切に対処できるプログラムを書くことができます。
連載第10回に当たる今回は、データの入出力について解説します。Rubyでは入出力、いわゆるI/Oをシンプルに扱うことができます。何気なく使ってきた「puts」も標準出力にデータを流すための立派なメソッドですし、IOクラスを利用することで、ファイルの入出力も可能です。
これまでの連載で「puts」メソッドを利用してターミナルに文字列を表示し、「画面に文字を表示する」と表現してきました。これは、「標準出力に文字列を出力する」と言った方が正しいでしょう。
特に意識せずにRubyスクリプトを流せば、標準出力に出力された文字はターミナルに表示されます。ただし、bashやそれに準ずるシェルを使っているならば、以下のようにRubyスクリプトを実行すると、標準出力がファイルに書き出されます。
$ ruby -e "puts 'pyon'" > rabbit.txt $ cat rabbit.txt
rubyコマンドに「-e」というオプションと文字列(ここでは「puts 'pyon'」)を与えると、文字列がRubyインタプリタによってスクリプトとして実行されます。また、「> rabbit.txt」は、標準出力に出力された文字をファイル(ここではrabbit.txt)に送るための記法です。
上述の一連のコマンドを実行すると、「puts」を実行しているにもかかわらず、ターミナルには何も表示されません。その代わりに、「cat」コマンドでrabbit.txtの内容をターミナルに流すと、「pyon」と出力されていることが分かるでしょう。
この辺りの話をしっかりと理解するためには、「UNIXの標準入出力とリダイレクション」が参考になるでしょう。筆者はWindowsに詳しくないため正確なことは言えませんが、おそらくWindowsにも似たような仕組みがあると思います。
ここでは、Kernelモジュールに定義されている入出力メソッドのうち、よく使われるものをいくつか紹介しましょう。
「print」メソッドは、最も基本的な出力メソッドの一つです。引数に与えられた文字列を標準出力に流します。返り値はnilです。pryを起動して動作を確かめてみましょう。
[1] pry(main)> print "Alice" Alice=> nil
「puts」メソッドも「print」と同様に最も基本的な出力メソッドの一つです。引数に与えられた文字列を標準出力に流しますが、「print」と違って最後に改行を行います。
[2] pry(main)> puts "Alice" Alice => nil
「printf」メソッドは、C言語における「printf」のように、sptintfフォーマットに基づく強力な書式付き出力を行うためのメソッドです。出力を行わずに単に書式適用済みの文字列を得たい場合は、「sprintf」メソッドが使えます。
詳細な記法については、Ruby公式の「sprintfフォーマット」をご覧ください。ここでは、簡単な例を紹介するにとどめます。
[4] pry(main)> printf("%.2f", 3.14159) 3.14=> nil [5] pry(main)> printf("%#b", 42) 0b101010=> nil [6] pry(main)> printf("%+d %d", 42, 42) +42 42=> nil
「printf」の第1引数にフォーマットを、第2引数以降に、表示したいオブジェクトを書きます。[4]では小数点以下の精度を2桁にとどめるような書式を設定しています。
また[5]では、42という整数を2進数で出力しています。[6]は整数を符号付きで表示する場合(`%+d`)と、特に書式指定なしに表示する場合「%d」を一度に表示するようなパターンです。
「gets」メソッドは、ユーザーによってキーボードから入力された文字列を得るためによく使われます。io01.rbに「gets」の利用例を示しましょう。
print "please input a string here > " p gets
$ ruby io01.rb please input a string here > Alice↵ "Alice\n"
io01.rbを実行すると、初めに「please input a string here > 」という文字列が表示され、ユーザーの入力を待ち受けます。実行例では「Alice」と入力してエンターキーを押しています。すると、実行結果の2行目のように「p」メソッドがユーザーの入力した内容を画面に表示します。
ここで、「gets」メソッドによって得た文字列には改行(\n)が含まれていることに注意してください。これを除去する典型的な方法として、「String#chomp」メソッドがあります。
print "please input a string here > " p gets.chomp
$ ruby io02.rb please input a string here > Alice "Alice"
ここで、テキストファイルを標準入力として使った場合の動作を観察してみましょう。以下のような内容を持つ、wonderland.txtというテキストファイルを作成してください。
Alice White Rabbit Cheshire Cat March Hare
では、io02.rbにwonderland.txtを入力してみましょう。
$ ruby io02.rb < wonderland.txt please input a string here > "Alice"
wonderland.txtは4行の文字列から成っており、「gets」がつかむのは初めに改行が登場するところまでです。これでは、複数行の入力を扱いたい場合に困ります。実は、「gets」をうまく使えば複数行の入力も扱えます。
while line = gets puts "** #{line.chomp} **" end
$ ruby io03.rb < wonderland.txt ** Alice ** ** White Rabbit ** ** Cheshire Cat ** ** March Hare **
io03.rbでは、whileループのたびに1行ずつ標準入力を読み込み、変数lineに代入しています。入力の末端(EOF:End of File)に達すると「gets」はnilを返すため、「line = gets」の評価値がnilとなり、無事whileループが終了します。
Copyright © ITmedia, Inc. All Rights Reserved.