열거형 enum · 간단한 사용 예

열거형 enum · 간단한 사용 예 (enumeration)

Raku의 enum 타입은 다른 언어들보다 훨씬 복잡한 축에 속해요. 그래서 여기서는 C 계열 언어에서 흔히 쓰는 방식, 그러니까 이름 붙은 상수들의 집합으로 enum을 쓰는 아주 간단한 예만 짚어보려고요. 더 자세한 내용은 타입 시스템 문서의 enum 설명을 참고하세요.

출처: Raku Docs — Enumeration

본문

상황을 하나 만들어 볼게요. 프로그램이 여러 디렉터리에 파일을 써야 한다고 합시다. 그러면 특정 디렉터리 이름을 받아 (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으로 자동 변환해 줘요. 마지막에 ~~ 스마트매치로 $statCanWrite인지 검사하는 부분도 편리하죠. enum을 쓰면 이렇게 상태값을 문자열로 오타 내지 않아도 되고, 서로 다른 상태를 하나의 타입 아래 묶을 수 있어요.