Ruby 1.8.7 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > ARGFオブジェクト

object ARGF

クラスの継承リスト: ARGF
extend: Enumerable

要約

スクリプトに指定した引数 (Object::ARGV を参照) をファイル名とみなして、 それらのファイルを連結した 1 つの仮想ファイルを表すオブジェクトです。 ARGV が空なら標準入力を対象とします。 ARGV を変更すればこのオブジェクトの動作に影響します。

while line = ARGF.gets
  ....
end

は、

while argv = ARGV.shift
  File.open(argv) {|file|
    while line = file.gets
      ....
    end
  }
end

のように動作します。

ARGF を処理するごとに ARGV の要素は一つずつ取り除かれます。 最後まで ARGF を読み込んだ後、再度 ARGF から内容を読むと (ARGV が空なので)標準入力からの読み込みとなります。

ARGV.replace %w(/tmp/foo /tmp/bar)
ARGF.each {|line|
    # 処理中の ARGV の内容を表示
    p [ARGF.filename, ARGV]
    ARGF.skip
}
    # => ["/tmp/foo", ["/tmp/bar"]]
    #    ["/tmp/bar", []]
# 最後まで読んだ後 (ARGV が空) の動作
p ARGF.gets      # => nil
p ARGF.filename  # => "-"

Kernel.#gets など一部の組み込み関数は ARGF.gets などこのオブジェクトをレシーバとしたメソッドの省略形です。

目次

特異メソッド
binmode bytes chars close closed? each each_line each_byte each_char eof eof? file filename path fileno to_i getbyte getc gets lineno lineno= lines pos tell pos= read readbyte readchar readline readlines to_a rewind seek skip to_io to_s

特異メソッド

binmode -> self[permalink][rdoc]

IO#binmodeを参照

require 'md5'

ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)
files = ARGV.dup
bm = ARGF.binmode.readlines(nil)
bm.each_with_index {|bl, i|
  md5 = MD5.new(bl).hexdigest
  printf("%s\t%s\n", md5, files[i])
}

#例
#=> fe413bf114e16b0cd596d869743e9d35        ruby-1.8.5-p35.tar.gz
#=> 70ad729e965c9625d2dfb7fa0145b423        sample.yaml
#=> d91e81b81673279e908a1c08e8582487        test.rb
#=> 158c4a0a097379a08bd88abfca6a51c5        test.rb~
#...

[SEE_ALSO] IO#binmode

bytes { |char| ... } -> self[permalink][rdoc]
bytes -> Enumerable::Enumerator

このメソッドは obsolete です。 代わりに ARGF.each_byte を使用してください。

self を 1 バイトずつ整数としてブロックの引数に繰り返しブロックを呼びだします。

ブロックを省略した場合には、 Enumerable::Enumerator オブジェクトを生成して返します。

ARGF.bytes.to_a        #=> [104, 101, 108, 108, 111]
chars { |c| ... } -> self[permalink][rdoc]
chars -> Enumerable::Enumerator

このメソッドは obsolete です。 代わりに ARGF.each_char を使用してください。

レシーバに含まれる文字を一文字つつブロックに渡して評価します。

レシーバは読み込み可能でなければなりません。

また、マルチバイト文字列を使用する場合は $KCODE を適切に設定してください。

[SEE_ALSO] ARGF.each_char

close -> self[permalink][rdoc]

処理対象のファイルをクローズします。開くファイルが残っている場合は次のファイルをオープンします。

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)
ARGF.each {|line|
  p [ line.chomp, ARGF.filename ]
  ARGF.close
  if ARGF.closed?
    p "ARGF is closed."
  else
    p "ARGF is not closed"
  end
}
if ARGF.closed?
  p "ARGF had been closed."
else
  p "ARGF is not closed"
end

#例
#=> ["cat:", "sample.yaml"]
#=> "ARGF is not closed"
#=> ["", "test.rb"]
#=> "ARGF is not closed"
#=> ["--- !ruby/object:Dog ", "ugo.yaml"]
#=> "ARGF is closed."
#=> "ARGF had been closed."
closed? -> bool[permalink][rdoc]

ARGFがcloseされていればtrueを返します。

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)
ARGF.each {|line|
  p [ line.chomp, ARGF.filename ]
  ARGF.close
  if ARGF.closed?
    p "ARGF is closed."
  else
    p "ARGF is not closed"
  end
}
if ARGF.closed?
  p "ARGF had been closed."
else
  p "ARGF is not closed"
end

#例
#=> ["cat:", "sample.yaml"]
#=> "ARGF is not closed"
#=> ["", "test.rb"]
#=> "ARGF is not closed"
#=> ["--- !ruby/object:Dog ", "ugo.yaml"]
#=> "ARGF is closed."
#=> "ARGF had been closed."

[SEE_ALSO] IO#closed?

each(rs = $/) {|line| ... } -> self[permalink][rdoc]
each_line(rs = $/) {|line| ... } -> self
each(rs = $/) -> Enumerable::Enumerator
each_line(rs = $/) -> Enumerable::Enumerator

ARGFの現在位置から一行ずつ文字列として読み込みます。

[PARAM] rs:
区切り文字を指定する
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)
ARGF.each_line {|line|
  line.chomp!
  printf("'%s' in %s\n", line, ARGF.filename)
}
#例
#=> '--- !ruby/object:Dog ' in ugo.yaml
#=> 'name: pochi' in ugo.yaml
#=> '--- ' in ugo.yaml
#=> ':age: 17' in ugo.yaml
#=> ':color: white' in ugo.yaml
#=> '--- ' in ugo.yaml
#=> '- Chiba' in ugo.yaml
#=> '- Saitama' in ugo.yaml

[SEE_ALSO] IO#each, IO#each_line,

each_byte {|char| ...} -> self[permalink][rdoc]
each_byte -> Enumerable::Enumerator

ARGF の現在位置から 1 バイトずつ読み込み、それを整数として与え、ブロックを実行します。

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)
ARGF.each_byte {|b|
  printf("%4d <-> %4s\n", b, b.chr)
}
#例
#=>  45 <->    -
#=>  32 <->
#=>  83 <->    S
#=>  97 <->    a
#=> 105 <->    i
#=> 116 <->    t
#=>  97 <->    a
#=> 109 <->    m
#=>  97 <->    a
#=>  10 <->
#...

[SEE_ALSO] IO#each_byte

each_char {|c| ... } -> self[permalink][rdoc]
each_char -> Enumerable::Enumerator

レシーバに含まれる文字を一文字つつブロックに渡して評価します。

レシーバは読み込み可能でなければなりません。

また、マルチバイト文字列を使用する場合は $KCODE を適切に設定してください。

[SEE_ALSO] IO#each_char, IO#chars

eof -> bool[permalink][rdoc]
eof? -> bool

現在開いているファイルがeofに達したらtrueを返します。そうでない場合はfalseを返します。

[EXCEPTION] IOError:
ファイルがopenされていない場合
# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)
ARGF.each_line {|line|
  if ARGF.eof
    printf("eof. %s has %d(%d) line\n", ARGF.filename, ARGF.file.lineno, ARGF.lineno)
  end
}
begin
  if ARGF.eof?
    printf("%s is eof\n", ARGF.filename)
  end
rescue IOError
  print "IOError !!\n"
end

#=> 例
#=> eof. sample.yaml has 13(13) line
#=> eof. test.rb has 159(172) line
#=> eof. test.rb~ has 159(331) line
#=> eof. third.txt has 1(332) line
#=> eof. ugo.yaml has 8(340) line
#=> IOError !!

[SEE_ALSO] IO#eof, IO#eof?

file -> IO[permalink][rdoc]

処理対象の File オブジェクト(または IO オブジェクト)を 返します。

ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)

until ARGF.closed?
  printf("最終更新時刻 %s (%s)\n", ARGF.file.stat.mtime, ARGF.filename)
  ARGF.skip
end
#例
#=> 最終更新時刻 Thu May 03 14:05:53 +0900 2007 (sample.yaml)
#=> 最終更新時刻 Sun Aug 26 11:28:09 +0900 2007 (test.rb)
#=> 最終更新時刻 Sun Aug 26 11:27:58 +0900 2007 (test.rb~)
#=> 最終更新時刻 Sun Jun 24 13:08:12 +0900 2007 (third.txt)
#=> 最終更新時刻 Sun May 20 21:34:25 +0900 2007 (ugo.yaml)

$stdinがIOオブジェクトでない場合は$stdinを返します。

class MyIO
  def to_io
    DATA
  end
end

$stdin = MyIO.new
ARGV.push("-");

p ARGF.file                #=> #<MyIO:0x293e840>
p ARGF.file.to_io.readline #=> "MyIO Test\n"

__END__
MyIO Test
です。

[SEE_ALSO] ARGF.to_io

filename -> String[permalink][rdoc]
path -> String

処理対象のファイル名を返します。 標準入力に対しては - を返します。 組み込み変数 $FILENAME と同じです。

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)
ARGF.each {|line|
  p [ARGF.filename, ARGF.path, ARGV]
  ARGF.skip
}
#例
#=> ["test.rb", "test.rb", ["test.rb~", "third.txt", "ugo.yaml"]]
#=> ["test.rb~", "test.rb~", ["third.txt", "ugo.yaml"]]
#...
fileno -> Integer[permalink][rdoc]
to_i -> Integer

現在オープンしているファイルのファイル記述子を表す整数を返します。

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)
ARGF.each_line {|line|
  p [ ARGF.to_i, ARGF.filename ]
  ARGF.skip
}
begin
  p [ ARGF.to_i, ARGF.filename ]
rescue ArgumentError
  print "ArgumentError\n"
end
#例
#=> [3, "sample.yaml"]
#=> [3, "test.rb"]
#=> [3, "test.rb~"]
#=> [3, "third.txt"]
#=> [3, "ugo.yaml"]
#=> ArgumentError
[EXCEPTION] ArgumentError:
getbyte -> Integer | nil[permalink][rdoc]

自身から 1 バイトを読み込み整数として返します。 既に EOF に達していれば nil を返します。

ARGF.getbyte   #=> 84
ARGF.getbyte   #=> 104
getc -> Integer | nil[permalink][rdoc]

ARGFから 1 文字読み込んで、その文字に対応する Fixnum を返します。EOF に到達した時には nil を返します。

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)

while c = ARGF.getc
  printf("%d,%c.\n", c, c)
end
#例
#=> 45,-.
#=> 32, .
#=> 67,C.
#=> 104,h.
#=> 105,i.
#=> 98,b.
#=> 97,a.
#=> 10,
#=> .
#...
gets(rs = $/) -> String | nil[permalink][rdoc]
gets(limit) -> String | nil
gets(rs, limit) -> String | nil

ARGFの現在位置から一行ずつ文字列として読み込みます。EOF に到達した時には nil を返します。

[PARAM] rs:
行の区切りを文字列で指定します。rs に nil を指定すると行区切りなしとみなします。 空文字列 "" を指定すると連続する改行を行の区切りとみなします(パラグラフモード)。
[PARAM] limit:
最大の読み込みバイト数
# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)

while line = gets
  line.chomp!
  printf("%s\n", line)
end

[SEE_ALSO] Kernel.#gets, [[m#IO#gets]]

lineno -> Integer[permalink][rdoc]

全引数ファイルを一つのファイルとみなしたときの現在の行番号を返します。 個々の引数ファイル毎の行番号を得るには ARGF.file.lineno とします。

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)
ARGF.each {|line|
  if ARGF.lineno < 10
    ARGF.lineno = 10
  end
  p [ ARGF.lineno, line]
}
#例
#=> [10, "cat:\n"]
#=> [11, " - name: taro\n"]
#=> [12, "   age: 7\n"]
#...
lineno=(number)[permalink][rdoc]

全引数ファイルを一つのファイルとみなしたときの現在の行番号を number に書き換えます。

[PARAM] number:
更新後の行番号を指定する
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)

ARGF.each {|line|
  if ARGF.lineno == 4
    ARGF.lineno = 5
  end
  p [ARGF.lineno, line]
}
#=> 例
#=> [1, "cat:\n"]
#=> [2, " - name: taro\n"]
#=> [3, "   age: 7\n"]
#=> [5, " - name: jiro\n"]
#=> [6, "   age: 23\n"]
# ...
lines(rs = $/) { |line| ... } -> self[permalink][rdoc]
lines(rs = $/) -> Enumerable::Enumerator

このメソッドは obsolete です。 代わりに ARGF.each_line を使用してください。

現在位置から 1 行ずつ文字列として読み込み、それを引数として 与えられたブロックを実行します。

ブロックが与えられなかった場合は、 Enumerable::Enumerator オブジェクトを生成して返します。

テキスト読み込みメソッドとして動作します。

[PARAM] rs:
行の区切りを文字列で指定します。rs に nil を指定すると行区切りなしとみなします。 空文字列 "" を指定すると連続する改行を行の区切りとみなします(パラグラフモード)。
ARGF.lines.to_a   #=> ["foo\n", "bar\n"]

[SEE_ALSO] $/, ARGF.each_line

pos -> Integer[permalink][rdoc]
tell -> Integer

ARGFが現在開いているファイルのファイルポインタの現在の位置を整数で返します。

ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)

while c = ARGF.getc
  printf("%d '%c' %s\n", ARGF.pos, c, ARGF.filename)
  if ARGF.pos == 3
    ARGF.skip
  end
end

# 例
#=> 1 'c' sample.yaml
#=> 2 'a' sample.yaml
#=> 3 't' sample.yaml
#=> 1 '#' test.rb
#=> 2 '!' test.rb
#=> 3 '/' test.rb
#=> 1 'd' third.txt
#=> 2 'r' third.txt
#=> 3 'y' third.txt
#...

[SEE_ALSO] IO#pos, IO#tell

pos=(n)[permalink][rdoc]

ARGFが開いているファイルのファイルポインタを指定位置に移動します。

[PARAM] n:
先頭からのオフセットを整数で指定します。
# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)
print ARGF.readline
#例
#=> #!/usr/bin/env ruby
ARGF.pos = 2
print ARGF.readline
#=> /usr/bin/env ruby
ARGF.pos = 4
print ARGF.readline
#=> sr/bin/env ruby

[SEE_ALSO] IO#pos=

read(length = nil, str = nil) -> String[permalink][rdoc]

ARGVに指定されたファイルを先頭のファイルからlengthバイト読み込み、 その文字列をstrに出力します。読み込んだ文字列を返します。

[PARAM] length:
読み込むバイト数を指定します nilの場合はARGVのすべてのファイルを読み込みます。
[PARAM] str:
出力先の文字列
# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)

str = "efefefe"
ARGF.read(100, str)
p str.size #=> 100
p str
# 例
#=> "cat:\n - name: taro\n   age: 7\n - name: jiro\n   age: 23\n---\ndog:\n shiba:\n- name: goro\n    age: 3\n  -"

[SEE_ALSO] IO#read

readbyte -> Integer[permalink][rdoc]

自身から 1 バイトを読み込み整数として返します。 既に EOF に達していれば EOFError が発生します。

[EXCEPTION] EOFError:
既に EOF に達している場合に発生します。
readchar -> Integer[permalink][rdoc]

ARGFから 1 文字読み込んで、その文字に対応する Fixnum を返します。EOF に到達した時には EOFErrorを発生します。

[EXCEPTION] EOFError:
EOFに達した時発生する
# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)

begin
  c = ARGF.readchar
  printf("%4c is %4d\n", c, c)
rescue EOFError
  p $!
  break
end while true

# 例
#...
#=>    t is  116
#=>    a is   97
#=>    m is  109
#=>    a is   97
#=>
#=>  is   10
#<EOFError: end of file reached>

[SEE_ALSO] ARGF.getc

readline -> String[permalink][rdoc]

ARGFの現在位置から一行ずつ文字列として読み込みます。EOF に到達した時にはEOFErrorを発生します。

[EXCEPTION] EOFError:
EOFに達したら発生する
# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)

begin
  line = ARGF.readline
  p line
rescue EOFError
  p $!
  break
end while true

#例
#...
#=> "- Saitama\n"
#=> <EOFError: end of file reached>

[SEE_ALSO] Kernel.#readline ARGF.gets

readlines(rs = $/) -> [String][permalink][rdoc]
to_a(rs = $/) -> [String]

ARGFの各行を配列に読み込んで返します。rsがnilの場合は要素に各ファイルをすべて読み込んだ配列を返します。

[PARAM] rs:
行区切り文字
# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)
aall = ARGF.readlines
p aall[0, 3]
# 例
#=> ["cat:\n", " - name: taro\n", "   age: 7\n"]
p ARGF.closed? #=> true

ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)

vsize = ARGV.size
aall = ARGF.readlines(nil)
p ARGF.closed? #=> true
p vsize == aall.size #=> true

[SEE_ALSO] $/ IO#readlines

rewind -> 0[permalink][rdoc]

ARGFが現在開いているファイルのファイルポインタを先頭に戻します。

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)

#各ファイルの先頭から3行を2回表示する
until ARGF.closed?
  1.upto(2){|i|
    printf("filename:%s at %d\n", ARGF.filename, i)
    1.upto(3){
      line = ARGF.readline
      p line
      break if ARGF.eof?
    }
    ARGF.rewind
  }
  ARGF.skip
end
seek(offset, whence = IO::SEEK_SET) -> 0[permalink][rdoc]

ARGFが現在開いているファイルのファイルポインタを whence の位置から offset だけ移動させます。 offset 位置への移動が成功すれば 0 を返します。

[PARAM] offset:
ファイルポインタを移動させるオフセットを整数で指定します。
[PARAM] whence:
IO#seekを参照
# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)

until ARGF.closed?
  begin
    ARGF.seek(-13, IO::SEEK_END)
    printf "(%s):%s", ARGF.filename, ARGF.readline
  rescue Errno::EINVAL
    printf "Error %s (%s)\n", ARGF.filename, $!.to_s
  end
  ARGF.skip
end
#例
#=> (sample.yaml):d of sample
#=> (test.rb):.skip
#=> (test.rb~):.skip
#=> Error third.txt (Invalid argument - third.txt)
#=> (ugo.yaml):

[SEE_ALSO] IO#seek

skip -> self[permalink][rdoc]

処理対象のファイルをクローズします。 次回の読み込みは次の引数が処理対象になります。 self を返します。

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)
while line = ARGF.gets
  p [ARGF.filename, ARGV, ARGF.skip]
end
#例
#=> ["sample.yaml", ["test.rb", "test.rb~", "third.txt", "ugo.yaml"], ARGF]
#=> ["test.rb", ["test.rb~", "third.txt", "ugo.yaml"], ARGF]
#...
to_io -> IO[permalink][rdoc]

ARGFが現在開いているファイルのFile、またはIOオブジェクトを返します

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").select{|name| FileTest.file?(name)}
)

until ARGF.closed?
  printf("最終更新時刻 %s (%s)\n", ARGF.to_io.stat.mtime, ARGF.filename)
  ARGF.skip
end
#例
#=> 最終更新時刻 Thu May 03 14:05:53 +0900 2007 (sample.yaml)
#=> 最終更新時刻 Sat Aug 18 16:31:42 +0900 2007 (test.rb)
#=> 最終更新時刻 Sat Aug 18 16:31:30 +0900 2007 (test.rb~)
#=> 最終更新時刻 Sun Jun 24 13:08:12 +0900 2007 (third.txt)
#=> 最終更新時刻 Sun May 20 21:34:25 +0900 2007 (ugo.yaml)
#...

$stdinがIOオブジェクトでない場合は$stdin.to_ioを呼び出します。

class MyIO
  def to_io
    DATA
  end
end

$stdin = MyIO.new
ARGV.push("-")

myio = ARGF.to_io
p myio.readline #=> "MyIO Test\n"
p ARGF.file     #=> #<MyIO:0x293ea34>

__END__
MyIO Test
です。

[SEE_ALSO] ARGF.file

to_s -> String[permalink][rdoc]

常に文字列 "ARGF" を返します。

# カレントディレクトリから適当にファイルを選ぶ
ARGV.replace(
  Dir.glob("*").reject{|name| FileTest.file?(name) == false}
)
while line = ARGF.gets
  p [ARGF.filename, ARGF.to_s, ARGV]
  ARGF.skip
end

#例
#=> ["test.rb", "ARGF", ["test.rb~", "third.txt", "ugo.yaml"]]
#=> ["test.rb~", "ARGF", ["third.txt", "ugo.yaml"]]
#...