클래스 Metamodel::EnumHOW

클래스 Metamodel::EnumHOW (Metamodel::EnumHOW) (raku-type-metamodel-enumhow)

경고: 이 클래스는 Rakudo 구현의 일부이고, 언어 명세의 일부는 아니에요.

enum 키워드 뒤에서 실제로 일을 하는 메타클래스가 Metamodel::EnumHOW예요.

class Metamodel::EnumHOW
    does Metamodel::Naming
    does Metamodel::Documenting
    does Metamodel::Stashing
    does Metamodel::AttributeContainer
    does Metamodel::MethodContainer
    does Metamodel::MultiMethodContainer
    does Metamodel::RoleContainer
    does Metamodel::BaseType
    does Metamodel::MROBasedMethodDispatch
    does Metamodel::MROBasedTypeChecking
    does Metamodel::BUILDPLAN
    does Metamodel::BoolificationProtocol
    does Metamodel::REPRComposeProtocol
    does Metamodel::Mixins
        { }

enum으로 만든 타입의 HOW가 바로 이 메타클래스인지 확인할 수 있어요.

enum Numbers <1 2>;
say Numbers.HOW ~~ Metamodel::EnumHOW; # OUTPUT: «True␤»

아래 enum 선언은

our Int enum Error <Warning Failure Exception Sorrow Panic>;

Metamodel::EnumHOW의 메서드들을 쓴 이 코드와 대략 동등해요.

BEGIN {
    my constant Error = Metamodel::EnumHOW.new_type: :name<Error>, :base_type(Int);
    Error.^add_role: Enumeration;
    Error.^add_role: NumericEnumeration;
    Error.^compose;
    for <Warning Failure Exception Sorrow Panic>.kv -> Int $v, Str $k {
        # 주의: Enumeration.pred 와 .succ 는 enum 값을 쌍으로 추가할 때는
        # 동작하지 않아요. enum 값들은 enum 그 자신의 인스턴스여야 하지만,
        # nqp 없이는 그렇게 만들 수 없어요.
        Error.^add_enum_value: $k => $v;
        OUR::{$k} := Error.^enum_from_value: $v;
    }
    Error.^compose_values;
    OUR::<Error> := Error;
}

method new_type

method new_type(:$name!, :$base_type?, :$repr = 'P6opaque', :$is_mixin)

enum을 위한 새 타입 객체를 만들어요. $name은 enum 이름, $base_type은 enum을 스코프 선언으로 선언했을 때 주어진 타입(있으면), $reprrepr 트레이트로 enum에 전달된 타입 표현이에요. $is_mixin은 사용되지 않아요.

method add_parent

method add_parent($obj, $parent)

enum의 기본 타입(base type)을 설정해요. .new_type에 기본 타입을 전달하지 않았을 때만 쓸 수 있어요.

method set_export_callback

method set_export_callback($obj, $callback)

enum의 export 콜백을 설정해요. 이 콜백은 .compose_values를 호출할 때 불려요. enum에 export 트레이트를 적용할 때 호출되는 것이죠. $callback은 인자를 받지 않고 enum의 값들을 export하는 일을 처리하는 어떤 루틴이면 돼요.

method export_callback

method export_callback($obj)

.set_export_callback으로 설정한 export 콜백을 돌려줘요.

method compose

method compose($obj, :$compiler_services)

enum을 위한 타입 객체를 완성해요. 이때 enum이 하는 역할(role)들이 섞여요. .add_enum_value로 enum 값을 추가하기 전에 반드시 호출해야 해요.

method is_composed

method is_composed($obj)

enum이 compose되었으면 1을, 아니면 0을 돌려줘요.

method compose_values

method compose_values($obj)

.set_export_callback으로 설정한 export 콜백을 호출하고 상태에서 제거해요. .add_enum_value로 enum 값을 추가한 뒤 호출해야 해요.

method set_composalizer

method set_composalizer($c)

enum의 composalizer를 설정해요. composalizer는 다른 타입과 섞일 수 있는 타입을 만들어 내죠. $c는 다음과 같은 시그니처를 가진 어떤 루틴이면 돼요.

:($type, $name, @enum_values)

method composalizer

method composalizer($obj)

.set_composalizer로 설정한 composalizer를 돌려줘요.

method add_enum_value

method add_enum_value($obj, $value)

이 enum에 값을 하나 추가해요. $valueEnumeration 타입으로서 enum 자신의 인스턴스여야 해요.

method enum_values

method enum_values($obj)

enum의 값들을 돌려줘요.

enum Numbers <10 20>;
say Numbers.^enum_values;                   # OUTPUT: {10 => 0, 20 => 1}

method elems

method elems($obj)

값의 개수를 돌려줘요.

enum Numbers <10 20>;
say Numbers.^elems;                         # OUTPUT: 2

method enum_from_value

method enum_from_value($obj, $value)

enum 기본 타입의 값을 주면, 그에 해당하는 enum을 돌려줘요.

enum Numbers <10 20>;
say Numbers.^enum_from_value(0);            # OUTPUT: 10

method enum_value_list

method enum_value_list($obj)

enum 값들의 리스트를 돌려줘요.

enum Numbers <10 20>;
say Numbers.^enum_value_list;               # OUTPUT: (10 20)

출처: Raku Docs - Metamodel::EnumHOW