ARGF 클래스

ARGF 클래스

ARGF는 명령줄 인자로 주어지거나 STDIN으로 전달되는 파일을 처리하는 스크립트를 위해 설계된 스트림이에요. 여러 파일을 연속된 하나의 입력처럼 다루는 데 쓰여요.

출처: Ruby 3.3 API

본문

스크립트에 전달된 인자는 ARGV 배열에 인자 하나당 요소 하나로 저장돼요. ARGF는 파일명이 아닌 인자는 ARGV에서 제거됐다고 가정해요. 예를 들어:

$ ruby argf.rb --verbose file1 file2

ARGV  #=> ["--verbose", "file1", "file2"]
option = ARGV.shift #=> "--verbose"
ARGV  #=> ["file1", "file2"]

이제 ARGF로 이 이름 붙은 각 파일의 연결(concatenation)을 다룰 수 있어요. 예를 들어 ARGF.read는 file1 다음에 file2의 내용을 이어 붙인 값을 반환해요.

ARGV의 파일을 읽고 나면 ARGF가 그 파일을 배열에서 제거해요. 따라서 모든 파일을 읽고 나면 ARGV가 비게 돼요.

ARGF가 동작할 대상을 제어하려면 ARGV를 직접 조작할 수 있어요. ARGV에서 파일을 제거하면 ARGF가 무시하고, 파일을 추가하면 명령줄에 이름을 적은 것처럼 취급해요. 예를 들어:

ARGV.replace ["file1"]
ARGF.readlines # Returns the contents of file1 as an Array
ARGV           #=> []
ARGV.replace ["file2", "file3"]
ARGF.read      # Returns the contents of file2 and file3

ARGV가 비어 있으면 ARGF"-"가 들어 있는 것처럼 동작해, STDIN(즉 스크립트로 파이프되거나 입력된 데이터)을 읽어요. 예를 들어:

$ echo "glark" | ruby -e 'p ARGF.read'
"glark\n"

$ echo Glark > file1
$ echo "glark" | ruby -e 'p ARGF.read' -- - file1
"glark\nGlark\n"

Public Instance Methods

argv → ARGV

스크립트에 전달된 인자를 요소 하나당 하나씩 담고 있는 ARGV 배열을 반환해요.

$ ruby argf.rb -v glark.txt

ARGF.argv   #=> ["-v", "glark.txt"]

binmode → ARGF

ARGF를 바이너리 모드로 전환해요. 일단 스트림이 바이너리 모드가 되면 다시 해제할 수 없어요. 다음과 같은 효과가 있어요.

  • 개행 변환 비활성화.
  • 인코딩 변환 비활성화.
  • 콘텐츠를 ASCII-8BIT로 취급.

binmode? → true or false

ARGF가 바이너리 모드로 읽히고 있으면 true, 그 외에는 false를 반환해요. 바이너리 모드를 켜려면 ARGF.binmode를 사용해요.

ARGF.binmode?  #=> false
ARGF.binmode
ARGF.binmode?  #=> true

close → ARGF

현재 파일을 닫고 ARGV의 다음 파일로 건너뛰어요. 열 파일이 더 없다면 현재 파일만 닫아요. STDIN은 닫히지 않아요.

$ ruby argf.rb foo bar

ARGF.filename  #=> "foo"
ARGF.close
ARGF.filename  #=> "bar"
ARGF.close

closed? → true or false

현재 파일이 닫혀 있으면 true, 그 외에는 false를 반환해요. 실제로 현재 파일을 닫으려면 ARGF.close를 사용해요.

each(sep=$/) {|line| block } → ARGF

each(sep=$/, limit) {|line| block } → ARGF

each(...) → an_enumerator

ARGV의 각 파일의 각 줄(기본값은 플랫폼의 개행 문자로 구분된 sep)을 순회하는 열거자(enumerator)를 반환해요. 블록이 주어지면 각 줄을 차례로 블록에 yield 하고, 아니면 열거자를 반환해요. 선택적 limit 인자는 각 줄의 최대 길이를 지정하는 정수이며, 더 긴 줄은 이 제한에 따라 잘라져요.

이 메서드로 명령줄에 제공된 파일들을 각 이름 붙은 파일의 연결로 이루어진 단일 파일처럼 다룰 수 있어요. 첫 파일의 마지막 줄을 반환한 뒤 두 번째 파일의 첫 줄을 반환해요. ARGF.filenameARGF.lineno로 각각 현재 줄의 파일명과 전체 입력 기준의 줄 번호를 알 수 있어요.

예를 들어, 다음 코드는 각 이름 붙은 파일의 각 줄을 줄 번호와 함께 출력하고 파일명은 파일당 한 번 표시해요.

ARGF.each_line do |line|
  puts ARGF.filename if ARGF.file.lineno == 1
  puts "#{ARGF.file.lineno}: #{line}"
end

반면 다음 코드는 처음에 첫 파일의 이름만 출력하고, 내용은 모든 이름 붙은 파일에 걸쳐 누적된 줄 번호와 함께 출력해요.

ARGF.each_line do |line|
  puts ARGF.filename if ARGF.lineno == 1
  puts "#{ARGF.lineno}: #{line}"
end

each_line의 별칭이기도 해요.

each_byte {|byte| block } → ARGF

each_byte → an_enumerator

ARGV의 각 파일의 각 바이트를 순회해요. 바이트는 0..255 범위의 Integer로 반환돼요. 명령줄의 파일들을 하나의 연결 파일처럼 다루며, 블록이 없으면 열거자를 반환해요.

ARGF.bytes.to_a  #=> [35, 32, ... 95, 10]

each_char {|char| block } → ARGF

each_char → an_enumerator

ARGF의 각 파일의 각 문자를 순회해요. 파일들을 하나의 연결 파일처럼 다루며, 블록이 없으면 열거자를 반환해요.

each_codepoint {|codepoint| block } → ARGF

each_codepoint → an_enumerator

ARGF의 각 파일의 각 코드포인트를 순회해요. 파일들을 하나의 연결 파일처럼 다루며, 블록이 없으면 열거자를 반환해요.

each_line(sep=$/) {|line| block } → ARGF

each_line(sep=$/, limit) {|line| block } → ARGF

each_line(...) → an_enumerator

각 줄을 순회하는 열거자를 반환해요. each의 동작과 같고, each의 별칭이에요.

ARGF.each_line do |line|
  puts ARGF.filename if ARGF.file.lineno == 1
  puts "#{ARGF.file.lineno}: #{line}"
end

eof → true or false

ARGF의 현재 파일이 파일 끝(EOF, 더 읽을 데이터가 없음)이면 true를 반환해요. 스트림은 읽기용으로 열려 있어야 하며, 아니면 IOError가 발생해요.

$ echo "eof" | ruby argf.rb

ARGF.eof?                 #=> false
3.times { ARGF.readchar }
ARGF.eof?                 #=> false
ARGF.readchar             #=> "\n"
ARGF.eof?                 #=> true

eof?의 별칭이기도 해요.

eof? → true or false

ARGF의 현재 파일이 EOF면 true를 반환해요. eof의 별칭이에요.

external_encoding → encoding

ARGF에서 읽은 파일의 외부 인코딩을 Encoding 객체로 반환해요. 외부 인코딩은 파일에 저장된 텍스트의 인코딩이에요. Ruby 내부에서 이 텍스트를 나타내는 데 쓰는 인코딩인 ARGF.internal_encoding과 대비돼요. 외부 인코딩을 설정하려면 ARGF.set_encoding을 사용해요.

ARGF.external_encoding  #=>  #<Encoding:UTF-8>

file → IO or File object

현재 파일을 IO 또는 File 객체로 반환해요. 현재 파일이 STDIN이면 $stdin을 반환해요.

$ echo "foo" > foo
$ echo "bar" > bar

$ ruby argf.rb foo bar

ARGF.file      #=> #<File:foo>
ARGF.read(5)   #=> "foo\nb"
ARGF.file      #=> #<File:bar>

filename → String

현재 파일명을 반환해요. 현재 파일이 STDIN이면 "-"를 반환해요.

$ echo "foo" > foo
$ echo "bar" > bar
$ echo "glark" > glark

$ ruby argf.rb foo bar glark

ARGF.filename  #=> "foo"
ARGF.read(5)   #=> "foo\nb"
ARGF.filename  #=> "bar"
ARGF.skip
ARGF.filename  #=> "glark"

path의 별칭이기도 해요.

fileno → integer

현재 파일의 숫자 파일 디스크립터를 나타내는 정수를 반환해요. 현재 파일이 없으면 ArgumentError를 던져요.

ARGF.fileno    #=> 3

to_i의 별칭이기도 해요.

getbyte → Integer or nil

ARGF에서 다음 8비트 바이트(0..255)를 가져와요. 스트림 끝에서 호출하면 nil을 반환해요.

$ echo "foo" > file
$ ruby argf.rb file

ARGF.getbyte #=> 102
ARGF.getbyte #=> 111
ARGF.getbyte #=> 111
ARGF.getbyte #=> 10
ARGF.getbyte #=> nil

getc → String or nil

ARGF에서 다음 문자를 읽어 String으로 반환해요. 스트림 끝에서는 nil을 반환해요. 명령줄에 이름 붙은 파일들을 하나의 연결 파일처럼 다룬다는 점에 주의하세요.

$ echo "foo" > file
$ ruby argf.rb file

ARGF.getc  #=> "f"
ARGF.getc  #=> "o"
ARGF.getc  #=> "o"
ARGF.getc  #=> "\n"
ARGF.getc  #=> nil
ARGF.getc  #=> nil

gets(sep=$/ [, getline_args]) → string or nil

gets(limit [, getline_args]) → string or nil

gets(sep, limit [, getline_args]) → string or nil

ARGF의 현재 파일에서 다음 줄을 반환해요. 기본적으로 줄을 $/로 구분한다고 가정하며, 다른 구분 문자를 쓰려면 sep 인자에 문자열로 주면 돼요. 선택적 limit 인자는 각 줄에서 반환할 문자 수를 지정하며, 기본적으로 모든 문자가 반환돼요. getline_args에 대한 자세한 내용은 IO.readlines를 참고하세요.

inplace_mode → String

인-플레이스 편집(in-place edit) 모드에서 수정된 파일의 백업 복사본 이름에 붙는 파일 확장자를 반환해요. 이 값은 ARGF.inplace_mode=로 설정하거나 Ruby 바이너리에 -i 스위치를 전달해 설정할 수 있어요.

inplace_mode = ext → ARGF

인-플레이스 편집 모드의 파일명 확장자를 주어진 String으로 설정해요. 편집 중인 각 파일의 백업 복사본 이름에 이 값이 붙어요.

$ ruby argf.rb file.txt

ARGF.inplace_mode = '.bak'
ARGF.each_line do |line|
  print line.sub("foo","bar")
end

먼저 file.txt.bak이 file.txt의 백업으로 생성되고, 그다음 file.txt의 각 줄에서 첫 번째 "foo""bar"로 바뀌어요.

internal_encoding → encoding

ARGF에서 읽은 문자열의 내부 인코딩을 Encoding 객체로 반환해요. ARGF.set_encoding이 인코딩 이름 두 개로 호출됐다면 두 번째가 반환돼요. 그 외에는 Encoding.default_external이 설정돼 있으면 그 값이, 명령줄에서 기본 외부 인코딩이 지정됐다면 그 값이 반환돼요. 인코딩을 알 수 없으면 nil을 반환해요.

lineno → integer

ARGF 전체의 현재 줄 번호를 반환해요. 이 값은 ARGF.lineno=로 수동 설정할 수 있어요.

ARGF.lineno   #=> 0
ARGF.readline #=> "This is line 1\n"
ARGF.lineno   #=> 1

lineno = integer → integer

ARGF 전체의 줄 번호를 주어진 Integer로 설정해요. ARGF는 데이터를 읽으며 줄 번호를 자동으로 설정하므로, 보통은 직접 설정할 필요가 없어요. 현재 줄 번호에 접근하려면 ARGF.lineno를 사용해요.

ARGF.lineno      #=> 0
ARGF.readline    #=> "This is line 1\n"
ARGF.lineno      #=> 1
ARGF.lineno = 0  #=> 0
ARGF.lineno      #=> 0

path → String

현재 파일명을 반환해요. 현재 파일이 STDIN이면 "-"를 반환해요. filename의 별칭이에요.

pos → Integer

현재 파일의 현재 오프셋(바이트 단위)을 반환해요. tell의 별칭이에요.

ARGF.pos    #=> 0
ARGF.gets   #=> "This is line one\n"
ARGF.pos    #=> 17

pos = position → Integer

ARGF에서 position(바이트 단위)이 주는 위치로 시크(seek)해요.

ARGF.pos = 17
ARGF.gets   #=> "This is line two\n"

print(*objects) → nil

주어진 객체들을 스트림에 쓰고 nil을 반환해요. 출력 레코드 구분자 $OUTPUT_RECORD_SEPARATOR($\)가 nil이 아니면 이를 붙여요.

objects 인자가 주어지면 각 객체에 대해:

  • 문자열이 아니면 to_s 메서드로 변환.
  • 스트림에 쓰기.
  • 마지막 객체가 아니면 출력 필드 구분자 $OUTPUT_FIELD_SEPARATOR($,)가 nil이 아니면 이를 쓰기.

기본 구분자 사용 시:

f = File.open('t.tmp', 'w+')
objects = [0, 0.0, Rational(0, 1), Complex(0, 0), :zero, 'zero']
p $OUTPUT_RECORD_SEPARATOR
p $OUTPUT_FIELD_SEPARATOR
f.print(*objects)
f.rewind
p f.read
f.close

출력:

nil
nil
"00.00/10+0izerozero"

구분자를 지정하면:

$\ = "\n"
$, = ','
f.rewind
f.print(*objects)
f.rewind
p f.read

출력:

"0,0.0,0/1,0+0i,zero,zero\n"

인자 없이 호출하면 $_(보통 가장 최근 사용자 입력)의 내용을 써요.

printf(format_string, *objects) → nil

objects를 포맷해서 스트림에 써요. format_string에 대한 자세한 내용은 Format Specifications를 참고하세요.

putc(object) → object

스트림에 문자 하나를 써요. object가 숫자면 필요한 경우 정수로 변환한 뒤, 최하위 바이트가 코드인 문자를 써요. object가 문자열이면 첫 문자를 써요.

$stdout.putc "A"
$stdout.putc 65

출력:

AA

puts(*objects) → nil

주어진 객체들을 스트림에 쓰고 nil을 반환해요. 각 객체 뒤에, 이미 개행 시퀀스로 끝나지 않았다면 개행을 하나 써요. 인자 없이 호출하면 개행만 써요. 여기서 추가되는 개행은 문자 "\n"이지 출력 레코드 구분자($\)가 아니라는 점을 주의하세요.

각 객체의 처리:

  • 문자열: 문자열을 씀.
  • 문자열도 배열도 아님: object.to_s를 씀.
  • 배열: 배열의 각 요소를 씀. 배열은 중첩될 수 있음.
def show(*objects)
  # Puts objects to file.
  f = File.new('t.tmp', 'w+')
  f.puts(objects)
  # Return file content.
  f.rewind
  p f.read
  f.close
end

# Strings without newlines.
show('foo', 'bar', 'baz')     # => "foo\nbar\nbaz\n"
# Strings, some with newlines.
show("foo\n", 'bar', "baz\n") # => "foo\nbar\nbaz\n"

# Neither strings nor arrays:
show(0, 0.0, Rational(0, 1), Complex(9, 0), :zero)
# => "0\n0.0\n0/1\n9+0i\nzero\n"

# Array of strings.
show(['foo', "bar\n", 'baz']) # => "foo\nbar\nbaz\n"
# Nested arrays.
show([[[0, 1], 2, 3], 4, 5])  # => "0\n1\n2\n3\n4\n5\n"

read([length [, outbuf]]) → string, outbuf, or nil

ARGF에서 length 바이트를 읽어요. 명령줄에 이름 붙은 파일들은 연결되어 이 메서드에서 단일 파일처럼 다뤄지므로, 인자 없이 호출하면 이 의사(pseudo) 파일의 내용 전체가 반환돼요.

length는 0 이상의 정수 또는 nil이어야 해요.

  • length가 양의 정수면, read는 변환 없이(바이너리 모드) length 바이트를 읽으려고 해요. 아무것도 읽기 전에 EOF를 만나면 nil을 반환하고, 읽기 중 EOF를 만나면 length보다 적은 바이트를 반환해요. 정수 길이의 경우 결과 문자열은 항상 ASCII-8BIT 인코딩이에요.
  • length가 생략되거나 nil이면 EOF까지 읽어요. 적용 가능하면 인코딩 변환이 적용돼요. 데이터를 읽기 전에 EOF를 만나도 문자열이 반환돼요.
  • length가 0이면 빈 문자열("")을 반환해요.

선택적 outbuf 인자가 있으면 String을 참조해야 하며 그 문자열이 데이터를 받아요. 인자 시작 시 비어 있지 않아도 메서드 호출 후에는 받은 데이터만 담게 돼요.

$ echo "small" > small.txt
$ echo "large" > large.txt
$ ./glark.rb small.txt large.txt

ARGF.read      #=> "small\nlarge"
ARGF.read(200) #=> "small\nlarge"
ARGF.read(2)   #=> "sm"
ARGF.read(0)   #=> ""

이 메서드는 C의 fread()처럼 동작해요. 즉 지정한 길이의 데이터를 읽기 위해 read(2) 시스템 호출을 재시도한다는 뜻이에요. 단일 read(2) 시스템 호출과 같은 동작이 필요하다면 ARGF#readpartial 또는 ARGF#read_nonblock을 고려하세요.

read_nonblock(maxlen[, options]) → string

read_nonblock(maxlen, outbuf[, options]) → outbuf

ARGF 스트림에서 비차단(non-blocking) 모드로 최대 maxlen 바이트를 읽어요.

readbyte → Integer

ARGF에서 다음 8비트 바이트를 읽어 Integer로 반환해요. 마지막 파일의 마지막 바이트를 읽은 뒤에는 EOFError를 발생시켜요.

$ echo "foo" > file
$ ruby argf.rb file

ARGF.readbyte  #=> 102
ARGF.readbyte  #=> 111
ARGF.readbyte  #=> 111
ARGF.readbyte  #=> 10
ARGF.readbyte  #=> end of file reached (EOFError)

readchar → String or nil

ARGF에서 다음 문자를 읽어 String으로 반환해요. 마지막 파일의 마지막 문자를 읽은 뒤에는 EOFError를 발생시켜요.

$ echo "foo" > file
$ ruby argf.rb file

ARGF.readchar  #=> "f"
ARGF.readchar  #=> "o"
ARGF.readchar  #=> "o"
ARGF.readchar  #=> "\n"
ARGF.readchar  #=> end of file reached (EOFError)

readline(sep=$/) → string

readline(limit) → string

readline(sep, limit) → string

ARGF의 현재 파일에서 다음 줄을 반환해요. 기본적으로 줄을 $/로 구분하며, 다른 구분 문자는 sep 인자에 문자열로 주면 돼요. 선택적 limit 인자는 각 줄에서 반환할 문자 수를 지정해요. 파일 끝에서는 EOFError가 발생해요.

readlines(sep = $/, chomp: false) → array

readlines(limit, chomp: false) → array

readlines(sep, limit, chomp: false) → array

ARGF의 각 파일을 전체 읽어, 파일들의 줄을 담은 Array를 반환해요. 줄은 sep으로 구분된다고 가정해요.

lines = ARGF.readlines
lines[0]                #=> "This is line one\n"

모든 옵션에 대한 자세한 설명은 IO.readlines를 참고하세요. to_a의 별칭이기도 해요.

readpartial(maxlen) → string

readpartial(maxlen, outbuf) → outbuf

ARGF 스트림에서 최대 maxlen 바이트를 읽어요. 선택적 outbuf 인자가 있으면 String을 참조해야 하며 받은 데이터만 담게 돼요. ARGF 스트림의 끝에서 EOFError를 발생시켜요. ARGF 스트림은 여러 파일의 연결이므로 내부적으로 각 파일마다 EOF가 발생해요. ARGF.readpartial은 마지막 파일을 제외한 EOF에서는 빈 문자열을 반환하고, 마지막 파일의 EOF에서 EOFError를 발생시켜요.

rewind → 0

현재 파일을 입력의 시작 위치로 옮기고 ARGF.lineno를 0으로 재설정해요.

ARGF.readline   #=> "This is line one\n"
ARGF.rewind     #=> 0
ARGF.lineno     #=> 0
ARGF.readline   #=> "This is line one\n"

seek(amount, whence=IO::SEEK_SET) → 0

whence 값에 따라 ARGF 스트림에서 amount(정수) 오프셋으로 시크해요. 자세한 내용은 IO#seek를 참고하세요.

set_encoding(ext_enc) → ARGF

set_encoding("ext_enc:int_enc") → ARGF

set_encoding(ext_enc, int_enc) → ARGF

set_encoding("ext_enc:int_enc", opt) → ARGF

set_encoding(ext_enc, int_enc, opt) → ARGF

단일 인자가 지정되면 ARGF에서 읽은 문자열이 지정된 인코딩으로 태그돼요. 콜론으로 구분된 두 인코딩 이름, 예를 들어 "ascii:utf-8"이 주어지면 읽은 문자열이 첫 인코딩(외부 인코딩)에서 두 번째 인코딩(내부 인코딩)으로 변환된 뒤 두 번째 인코딩으로 태그돼요. 두 인자가 지정되면 인코딩 객체 또는 인코딩 이름이어야 하고, 첫 번째가 외부 인코딩, 두 번째가 내부 인코딩이에요. 외부/내부 인코딩이 지정되면 선택적 Hash 인자로 변환 과정을 조정할 수 있어요. 이 해시 구조는 String#encode 문서에 설명돼 있어요.

ARGF.set_encoding('ascii')         # Tag the input as US-ASCII text
ARGF.set_encoding(Encoding::UTF_8) # Tag the input as UTF-8 text
ARGF.set_encoding('utf-8','ascii') # Transcode the input from US-ASCII
                                   # to UTF-8.

skip → ARGF

현재 파일을 ARGV의 다음 파일로 설정해요. 더 이상 파일이 없으면 효과가 없어요.

$ ruby argf.rb foo bar
ARGF.filename  #=> "foo"
ARGF.skip
ARGF.filename  #=> "bar"

tell → Integer

현재 파일의 현재 오프셋(바이트 단위)을 반환해요. pos의 별칭이기도 해요.

ARGF.pos    #=> 0
ARGF.gets   #=> "This is line one\n"
ARGF.pos    #=> 17

to_a(sep = $/, chomp: false) → array

to_a(limit, chomp: false) → array

to_a(sep, limit, chomp: false) → array

ARGF의 각 파일을 전체 읽어 줄들을 담은 Array를 반환해요. readlines의 별칭이에요.

to_i → integer

현재 파일의 숫자 파일 디스크립터를 나타내는 정수를 반환해요. 현재 파일이 없으면 ArgumentError를 던져요. fileno의 별칭이에요.

to_io → IO

현재 파일을 나타내는 IO 객체를 반환해요. 현재 파일이 STDIN 같은 스트림이 아니면 File 객체가 돼요.

ARGF.to_io    #=> #<File:glark.txt>
ARGF.to_io    #=> #<IO:<STDIN>>

to_s → String

"ARGF"를 반환해요. inspect의 별칭이기도 해요.

to_write_io → io

인플레이스 모드가 활성화돼 있으면 쓰기용으로 ARGF에 연결된 IO 인스턴스를 반환해요.

write(string) → integer

인플레이스 모드이면 string을 써요.