역할 Associative
역할 Associative (Associative) (raku-type-associative)
이름으로 값을 찾아내는 타입, 그러니까 % 시길문자를 쓰는 변수들이 공통으로 지키는 약속이 있어요. 그 약속을 끼워 두는 곳이 Associative 역할이에요. Hash나 Map처럼 { }를 이용해 키로 값을 찾는 타입들이 이 역할을 하는데, 특정 메서드를 호출해야 하는 연산자들이 타입을 검사할 때도 이 역할을 확인해요. 자세한 내용은 서브스크립트 문서를 참고하면 좋아요.
role Associative[::TValue = Mu, ::TKey = Str(Any)] { }
% 시길문자는 변수를 Associative를 하는 객체로 제한해요. 그래서 내가 만든 클래스를 % 시길문자와 함께 쓰고 싶다면, 그 클래스에 이 역할을 섞어 줘야 해요. 섞지 않으면 어떻게 될까요? 아래처럼 타입 검사가 실패해요.
class Whatever {};
my %whatever := Whatever.new;
# OUTPUT: «Type check failed in binding; expected Associative but got Whatever
여기서 := 바인딩을 쓴 점에 주목해요. 기본적으로 % 자리에는 Hash가 오기를 기대해서, 대입(=)을 쓰면 값이 해시로 변환되려고 시도하다가 역시 실패하거든요. 그런데 Associative 역할을 섞으면 이런 선언이 문법적으로 맞아요.
class Whatever is Associative {};
my %whatever := Whatever.new;
method of
method of()
Associative는 위 정의에서 봤듯 실제로는 파라미터화된 역할이라, 키와 값에 서로 다른 클래스를 쓸 수 있어요. 문서 맨 위에서 봤듯 기본적으로는 키를 Str로 강제하고 값은 아주 일반적인 Mu를 써요.
my %any-hash;
say %any-hash.of; # OUTPUT: «(Mu)»
특정 클래스로 Associative를 인스턴스화하면, 그때 첫 번째 파라미터가 값의 타입이 돼요.
class DateHash is Hash does Associative[Cool,DateTime] {};
my %date-hash := DateHash.new;
say %date-hash.of; # OUTPUT: «(Cool)»
method keyof
method keyof()
Associative 역할에서 쓰는 파라미터화된 키를 돌려줘요. 기본값은 Any를 Str로 강제한 값이에요. 파라미터화된 버전의 Associative를 쓸 때 두 번째 파라미터로 주는 클래스가 바로 이 값이에요.
my %any-hash;
%any-hash.keyof; # OUTPUT: «(Str(Any))»
Associative를 섞는 클래스가 제공해야 하는 메서드
키로 값을 접근하는 { } 연산자를 제대로 쓰려면 클래스가 Associative 역할을 제대로 구현해야 해요. 그런데 이 메서드들이 반드시 필수는 아니에요. 반대로, 그냥 어떤 클래스의 객체에 { }를 쓰고 싶다면 Associative 역할을 섞지 않고도 이 메서드들만 구현하면 돼요.
method AT-KEY
method AT-KEY(\key)
주어진 키에 해당하는 값이나 컨테이너를 돌려줘야 해요.
class What { method AT-KEY(\key) { 42 }};
say What.new{33}; # OUTPUT: «42»
method EXISTS-KEY
method EXISTS-KEY(\key)
주어진 키에 실제로 값이 있는지를 나타내는 Bool을 돌려줘야 해요.
method STORE
method STORE(\values, :$INITIALIZE)
Associative 역할을 구현한 내 타입을 아래 문법으로 바인딩하고 싶을 때만 이 메서드를 제공하면 돼요.
my %h is Foo = a => 42, b => 666;
객체를 (재)초기화할 값들을 받아야 하고, 그 값들은 Pair들이거나 키/값이 따로따로인 쌍일 수 있어요. 객체에 처음 호출될 때는 선택적 이름 파라미터가 True 값을 담고 있어요. 그리고 invocant를 돌려줘야 해요.
함께 보기
Associative 역할을 위해 추가로 구현할 수 있는 메서드에 대한 내용은 연관 서브스크립트 메서드 구현 문서를 참고하면 돼요.