IO::ArgFiles — 명령줄에 지정된 파일 내용 순회
IO::ArgFiles — 명령줄에 지정된 파일 내용 순회
프로그램에 명령줄 인자로 넘겨진 파일들을 차례로 읽고 싶을 때가 있어요. IO::ArgFiles 클래스는 바로 그 일을 해주는 클래스예요. 다만 이 클래스는 하위 호환성을 위해 존재하며, IO::CatHandle에 추가 메서드를 제공하지 않아요. 그래서 IO::CatHandle과 똑같은 방식으로 쓸 수 있어요.
class IO::ArgFiles is IO::CatHandle { }
예를 들어 이렇게 쓰죠.
my $argfiles = IO::ArgFiles.new(@*ARGS);
.say for $argfiles.lines;
raku io-argfiles.raku *.raku처럼 호출하면 그 디렉터리의 확장자가 .raku인 모든 파일의 내용을 출력해요. 그런데 이것은 사실 완전히 다음 코드와 동일해요.
my $argfiles = IO::CatHandle.new(@*ARGS);
.say for $argfiles.lines;
본문
변수 (Variables)
$*ARGFILES
이 클래스는 $*ARGFILES 변수의 마법 뒤에 숨은 존재예요. $*ARGFILES는 프로그램에 명령줄로 넘겨진 파일들(즉 @*ARGS의 요소들)을 순회할 방법을 제공하죠. 그래서 위 예시들은 이렇게 단순해져요.
.say for $*ARGFILES.lines;
# 또는
while ! $*ARGFILES.eof {
say $*ARGFILES.get;
}
# 또는
say $*ARGFILES.slurp;
위 변형 중 하나를 argfiles.raku라는 파일에 저장해보세요. 그리고 sonnet18.txt라는 다른 파일을 만들어 다음 내용을 넣어보죠.
Shall I compare thee to a summer's day?
그다음 명령을 실행하면,
$ raku argfiles.raku sonnet18.txt
다음 출력이 나와요.
Shall I compare thee to a summer's day?
6.d 언어부터 $*ARGFILES는 sub MAIN 안에서는, @*ARGS가 비어 있지 않아도 항상 $*IN으로 설정돼요. 즉 다음 코드는,
sub MAIN () {
.say for $*ARGFILES.lines;
}
예를 들어 cat *.raku | raku argfiles-main.raku처럼 쓸 수 있는데, 이것은 완전히 다음 코드와 동일해요.
sub MAIN () {
.say for $*IN.lines;
}
그리고 사실 이 경우에는 명령줄의 인자를 처리할 수 없어요. 그렇게 하면 사용법(usage) 오류가 나기 때문이죠.
$*ARGFILES 객체가 명령줄의 모든 인자에 대한 핸들을 담고 있다는 점을 기억하세요. 그 인자가 유효한 파일이 아니어도 그래요. 그 핸들은 .handles 메서드로 가져올 수 있어요.
for $*ARGFILES.handles -> $fh {
say $fh;
}
인자 중 하나라도 유효한 파일 이름이 아니면 그 코드는 실패해요. 그 경우는 다른 수준에서 처리해야 해요. 예를 들어 @*ARGS가 유효한 파일 이름을 담고 있는지 검사하는 식이죠.