열거형 enum · 간단한 사용 예
열거형 enum · 간단한 사용 예 (enumeration)
Raku의 enum 타입은 다른 언어들보다 훨씬 복잡한 축에 속해요. 그래서 여기서는 C 계열 언어에서 흔히 쓰는 방식, 그러니까 이름 붙은 상수들의 집합으로 enum을 쓰는 아주 간단한 예만 짚어보려고요. 더 자세한 내용은 타입 시스템 문서의 enum 설명을 참고하세요.
본문
상황을 하나 만들어 볼게요. 프로그램이 여러 디렉터리에 파일을 써야 한다고 합시다. 그러면 특정 디렉터리 이름을 받아 (1) 그 디렉터리가 존재하는지, (2) 프로그램 사용자가 거기에 쓸 수 있는지, 두 가지를 검사하는 함수가 필요해요. 사용자 입장에서 볼 때 상태는 세 가지가 돼요. 쓸 수 있거나(CanWrite), 디렉터리가 없거나(NoDir), 디렉터리는 있는데 쓸 수 없거나(NoWrite)죠. 검사 결과에 따라 프로그램이 다음에 할 일이 달라져요.
enum DirStat <CanWrite NoDir NoWrite>;
sub check-dir-status($dir --> DirStat) {
if $dir.IO.d {
# 디렉터리가 존재한다면, 프로그램 사용자가 여기에 쓸 수 있는가?
my $f = "$dir/.tmp";
spurt $f, "some text";
CATCH {
# 어떤 이유로든 쓸 수 없음
return NoWrite;
}
# 여기까지 오면 디렉터리에 쓸 수 있다는 뜻
unlink $f;
return CanWrite;
}
# 여기까지 오면 디렉터리가 존재하지 않음
return NoDir;
}
# 비-root 사용자로 세 디렉터리를 각각 검사
my @dirs = (
'/tmp', # 보통 어떤 사용자든 쓸 수 있음
'/', # root만 쓸 수 있음
'~/tmp' # 사용자 홈 디렉터리에는 존재하지 않는 디렉터리
);
for @dirs -> $dir {
my $stat = check-dir-status $dir;
say "status of dir '$dir': $stat";
if $stat ~~ CanWrite {
say " user can write to dir: $dir";
}
}
# output
# status of dir '/tmp': CanWrite
# user can write to dir: /tmp
# status of dir '/': NoWrite
# status of dir '~/tmp': NoDir
여기서 눈여겨볼 점이 몇 개 있어요. 함수의 반환 타입을 --> DirStat으로 선언해서, 반환값이 항상 enum의 멤버 중 하나라는 걸 컴파일러가 알게 해요. 그리고 NoWrite처럼 enum 멤버를 그냥 값처럼 return하면 Raku가 DirStat enum으로 자동 변환해 줘요. 마지막에 ~~ 스마트매치로 $stat이 CanWrite인지 검사하는 부분도 편리하죠. enum을 쓰면 이렇게 상태값을 문자열로 오타 내지 않아도 되고, 서로 다른 상태를 하나의 타입 아래 묶을 수 있어요.