すごい単純な例なのですが、$<.close の効果に気がつかなくて...
■ Ruby で head(1)
Ruby で UNIX の基本ツールの一つ head(1) を作ってみました。
ファイルを扱う際の基本パターンですので、小さいですが基本パ
ターン? になっているように思います。
■ ファイルを扱う基本パターン
ファイルを表示するだけの cat(1) との同等品は、Ruby ではつ
ぎのように書きます。
------------------------------
#! /usr/local/bin/ruby
# Created: February 21,1998 Saturday 18:41:43
while gets
print
end
exit
------------------------------
gets は、便利な機能を持っています。gets は一行読み込んで
きます。引数がなければ「$<」(ARGV) でアクセスできる仮想的
なファイルから読み込みます。これは、コマンドライン上で指
定した一連の「ファイル」または、標準入力になります。Perl
では
------------------------------
while (<>) {
# 一行が $_ に入力される
}
------------------------------
でよく処理するものです。
■ $. と $<
ちょっと悩んだのが、$. の扱いです。Perl と同様に $. は、
「最後に読んだ入力ファイルの行番号」と定義されています。
head(1) の処理場合、必要行数を表示したら次のファイルの処
理を行います。このときの方法がよく分かりませんでした。マ
ニュアルやサンプルを参照してみたのですが...
Perl では、現在扱っているファイルを明示的に close するこ
とで、すべてがうまく行きます。$. をリセットします。きっと
Ruby でも同様の方法があると思い確認した結果が次のソースコー
ドにある方法です。$<.close を実施することで、Perl とまっ
たく同じに現在の扱っているファイルがクローズされます。そ
して $. で示される行番号もリセットされます。
実はこれに気がつくまで $<.file.close とやっていて失敗して
いました。ちょっと気がつかなくて...
■ ソースコード
------------------------------
#! /usr/local/bin/ruby
# Created: February 22,1998 Sunday 09:30:21
# Author: tetsu(WATANABE Tetsuya)
def usage
STDERR.print "usage: #$0 [-number] [files ...]\n"
exit 1
end
lines = 10
while $_ = ARGV[0] and /^-/
ARGV.shift
if /^-(\d+)$/; lines = Integer($1); next end
usage
end
while gets
print '==> ', $<.filename, " <==\n" if $. == 1
if $. > lines
$<.close
else
print
end
end
exit
------------------------------
次のソースコードは便利な方法を使わず、ほとんどを C のプロ
グラムと同じレベルで記述しているものです。どちらもやって
いることは同等なのですが...
------------------------------
#! /usr/local/bin/ruby
# Created: February 21,1998 Saturday 18:23:42
# Author: tetsu(WATANABE Tetsuya)
def usage
STDERR.print "usage: #$0 [-number] [files ...]\n"
exit 1
end
lines = 10
while $_ = ARGV[0] and /^-/
ARGV.shift
if /^-(\d+)$/; lines = Integer($1); next end
usage
end
n = ARGV.length
if n == 0
while gets
print
break if $. >= lines
end
else
while file = ARGV.shift
print "==> #{file} <==\n" if n > 1
f = File.open(file)
while f.gets
print
break if $. >= lines
end
f.close
end
end
exit
------------------------------
--
WATANABE Tetsuya HP Japan PSO
e-mail tetsu / jpn.hp.com