情報科学概論
2002.6.25
出席に関する注意事項を説明しますので,その注意を良く聞いてから,電子メールにより出席の申告をしてください.「件名」は
gairon 6-25 attend s0240**
のように自分の学生番号を使って下さい.なお,入力ミスがあると出席として認
められないことになりますので,慎重に行ってください.文
字はすべて1バイト文字 (半角英数字) です.途中に入るスペースは一度に一個だけと
してください.スペースは全部で3個です.また,**の部分は自分の学生番号の下二桁
です.
これまで,スクリプトを実行するときに何らかの入力が必要なものについては,
コマンドライン引数で与えたり,シェルのリダイレクト機能を利用したりしまし
た.また,出力をシェルのパイプライン機能を利用してシェルに流すことも行い
ました.ここでは,既に存在しているファイルをスクリプトから開いて作業する
ことや結果をファイルに保存する「入出力」について説明します.
open と言うメソッドを利用してディレクトリにあるファイルを開きま
す.作業しているディレクトリに open.txt
というファイルがあるとします.中身は,次のようなものを例として挙
げますが,何でも構いません.
すると,最も単純な例として,次のようなスクリプトが考えられます.
これを実行するには,コマンドラインで,
$ ruby file.rb
としてみましょう.ファイルの中身が表示されます.これまでにもいろいろと中
身を表示するスクリプトを作成してきましたが,ここでは始めて open
というメソッドを使いました.読んで字のごと
く,ファイルを「開く」メソッドです.また,開いた
だけでは,中身が取り出せないので,read
メソッドにより本文を抽出しています.
上の例では,カレントディレクトリにあるファイルのみを想定していましたが,
ファイルの所在を示す方法には絶対パスや相対パスのような表記があることを学
習していますので,その応用を考えてみましょう.次のようにスクリプトのファ
イル名部分を変更すると,結果はどうなるでしょうか.
open メソッドではファイル名指定にホームディレクトリを表す ~
は使えません.絶対パス指定とするか,相対パ
スで指定するかしなければ開けません.
ここまでの例では,読み込むべきファイルの名前がスクリプトの中に記述されているの
で,いろいろとファイルを見たい場合には不便です.ファイル名をコマンドライ
ン引数で与えるように改良してみましょう.
いつものように,コマンドライン引数を扱う定数 ARGV を使用してい
ます.先ほどと少し違うのは,開いたファイルを閉じる操作 close が
使われています.開いたファイルはちゃんと閉じておくのが本来の決まりです.
上の例で使われている read はファイル全体をいったんメモリに蓄え
ます.open.txt のような簡単なファイルであれば問題はありませんが,
何千行,何万行とあるデータだとメモリをたくさん使用して処理の低下を招きま
す.1行ずつ読み込むためには,これまでもずっと使ってきた gets が
良いでしょう.
動作結果は read を使った場合と変らないように見えます.しかし,
使用しているメモリは gets を使う場合には1行文のデータ量ですので,
動作自体はずいぶんと軽くなっているのです.
UNIXのファイルシステムにおいては属性の指定が可能であり,読込や書き込みの
権限がついています.ファイルをRubyから開く際にも属性が問題になります.次
に示すファイルのコピーを行うスクリプトではコピー元を読み込み専用,コピー
先を書き込み専用の属性をつけて読み込み,動作させるようにしています.また,
コピー先となるファイルはあらかじめ作っておく必要はありません.書き込みモー
ドを指定すると,Rubyの方で作ってくれます.
open メソッドのかっこの中に属性が指定してあり,"r" が
読み込み属性,"w" が書き込み属性です.
また, << はシェルのリダイレクト
で使用されるのと同じように,出力先を指定するもの
で,ソースからターゲットに向けてデータが写されま
す.
動作にはコマンドライン引数を2つ使用します.一つめがコピー元,二つ目がコピー先の
名前となりますので,通常のターミナルにおけるコピーコマンドと同じ動作です.
例えば,次のようにして使用します.
$ ruby copy.rb open.txt another.txt
上の例を自分で工夫しながら試してみてください.
ここまでの理解度をチェックするための復習を行います.時間が来ればア
ナウンスしますので,しばらくお待ち下さい.
授業の終りに宿題 (AクラスとBクラス別々) について説明しますので,アナウンスに注意してください.
1st line
2nd line
3rd line
4th line
last line
#file.rb
file = open("open.txt")
print file.read
file = open("~/.bash_history")
file = open("/etc/skel/.canna")
#name.rb
name = ARGV[0]
file = open(name)
print file.read
file.close
#gets.rb
name = ARGV[0]
file = open(name)
while line = file.gets
print line
end
file.close
#copy.rb
source = ARGV[0]
target = ARGV[1]
s_file = open(source, "r")
t_file = open(target, "w")
t_file << s_file.read
s_file.close
t_file.close
ページトップに戻る