変数 filename (文字列)に対象となるファイル名が入っているとして、
ifile=File.open(filename)
puts ifile.read
ifile.close
のように、Fileオブジェクトを ① オープン ② 利用(ここでは read)③ クローズ の順で使う。
IO#read
(IO クラスの read
インスタンスメソッド)を、File クラスが継承しているもの。gets, puts,
write なども同様。File#open のドキュメント には、3つのAPI(呼び出し方)が書かれていて、
前章の例は以下のように書き換えることができる。
File.open(filename) do |ifile|
puts ifile.read
end
なお、上記の例ではブロックを do ~ end で囲んだが、
(C,Java,JavaScript 等の言語と同様に){
~ }
で囲む書き方も使える(ドキュメントではその書き方で書かれている)。
また、File.#open の代わりに Kernel.#open を使うこともできる。
この場合、前置される Kernel.
は省略可能なので、つまりは、
File.open ではなく 単に open と書いてもいいことになる。
.bak
を付加した名前、ということにしておく。まとめて読んでまとめて書く(ソース)
File.open(filename) do |ifile|
content=ifile.read
end
File.open(filename+".bak","w") do |ofile|
ofile.write(content)
end
入力用 出力用 2つのファイルを同時にオープンする(ソース)
File.open(filename) do |ifile|
File.open(filename+".bak","w") do |ofile|
content=ifile.read
ofile.write(content)
end
end
2.と同様に入れ子にして、readで読み込んだ値を、write の引数として渡す。(ソース)
File.open(filename) do |ifile|
File.open(filename+".bak","w") do |ofile|
ofile.write(ifile.read())
end
end
ブロックの中のコードは、ofile.write ifile.read
でも構わない(puts gets
で学んだのと同様)。
なお、実演の際に、ブロック変数の名前として in
を使った際にエラーが発生した(これは予約語だから)。
実行時に値を与える方法として、コマンドラインパラメータがある。
コマンドラインパラメータは、配列 ARGV に入れて渡される。
これをプログラムで使うときは、配列の要素として取り出せばいい。
1つ目の語を(文字列として)取り出すためには、 ARGV[0]
ARGV.shift
といった書き方ができる(配列へのアクセスの方法がいろいろあるので、その中から
使えるものを使うことになる)。
Array#[]
メソッド、 後者は Array#shift
という破壊的な(もとの配列の状態を変化させる)メソッドを使った書き方。filename=ARGV.shift
これでも目的の動作はするが、もしファイル名をコマンドラインパラメータとして渡さずに(つまりコマンドラインパラメータなしで)呼び出した時にエラーが発生する、それを避けることも考えておこう。
[]
(つまり空の配列)が与えられていて、ARGV.shift
も ARGV[0]
も値 nil
を返す。# if式 による条件判定を使って
if((filename=ARGV.shift) == nil) then exit end
# 真のときの thenパートが空で、elseパートに exit を書く
if (filename=ARGV.shift) then else exit end
# if の反対の意味の unless を使って
unless (filename=ARGV.shift)) then exit end
# not (論理否定)で真偽を反転させる
if (not filename=ARGV.shift) then exit end
# not の代わりに 単項演算子 ! を使う
if (! filename=ARGV.shift) then exit end
# 同じ意味の、!メソッド(Object#!)を使う
# (このときは代入式を括弧で囲む必要がある)
if ((filename=ARGV.shift).!) then exit end
関数的センスで書くことの多い言語の場合、上記は、演算子 ||
を使ってもっと簡潔に書かれる。
(filename=ARGV.shift) || exit
||
の代わりに、演算子 or
を使ってもいい。
この演算子については、たとえばこのようなqiitaの記事 を参照下さい。
演算子 and
, or
, &&
, ||
の(Rubyでは)4つは、「短絡評価」される演算子。
conditional-AND, conditional-OR という呼び方もある。
短絡評価においては、演算子の右辺は評価(実行)されない場合がある。それは左辺の値(結果)に左右される。
例えば ||
では、左辺が偽値(false か
nil)の場合、次に右辺が評価され、右辺の値が式全体の値になり
(上の式では右辺がexit
なので値は返されず代わりにプログラムが終了するのだが)、
左辺が真値(false nil 以外の任意の値)の場合は、その左辺の値 (つまり上記の式では filenameに代入された値)式全体の値として 返され、右辺は評価されず無視される。
これが 前項の、if や unless を使った条件分岐と同じ意味になることを、じっくり(場合分けをして)考えて納得しておいて下さい。