`append`

append (컬렉션 끝에 값 이어 붙이기)

배열이나 해시 같은 컬렉션에 값을 끝에 덧붙이는 일은 아주 흔하죠. Raku에는 push도 있지만, 각 컬렉션 타입마다 값을 이어 붙이는 방식이 조금 달라요. 그 규칙을 통일해서 잡아주는 메서드가 append예요.

출처: Raku Documentation — routine append

본문

Independent routines

multi append(\a, **@b is raw)
multi append(\a, \b)

첫 번째 인자의 append 메서드를 호출하고, 나머지 인자들을 그대로 넘겨요. append 메서드는 주어진 값들을 컬렉션의 끝(또는 그 일부)에 더하는 걸 목적으로 해요. push 메서드와 달리 append는 단일 인자 규칙(single argument rule)을 따라야 해요. 그래서 새 컬렉션 타입에 규칙에 맞는 append 메서드를 구현하려 한다면, 시그니처가 다음과 같다고 보면 돼요.

multi method append(::?CLASS:D: +values --> ::?CLASS:D)

push 루틴과 비슷하게, 자동 생식(autovivification)을 지원하려면 multi 메서드를 하나 더 추가해야 할 수 있어요.

multi method append(::?CLASS:U: +values --> ::?CLASS:D)

append의 서브루틴 형태는 Hash의 값에 이어 붙일 때 유용해요. 메서드 형태는 리터럴 Pair를 이름 인자로 해석해서 조용히 무시해버리지만, 서브루틴 형태는 예외를 던지거든요.

my %h = i => 0;
append %h, i => (1, 42);
CATCH { default { put .message } };
# OUTPUT: «Unexpected named argument 'i' passed␤»

Any

multi method append(Any:U \SELF: |values)

인스턴스가 위치 방식 값이 아니라면 새 Array로 인스턴스화하고, 그렇지 않으면 현재 인스턴스를 복제해요. 그 뒤 인자로 넘긴 값들을 얻은 배열에 Array.append를 호출해 이어 붙여요.

my $a;
say $a.append; # OUTPUT: «[]␤»
my $b;
say $b.append((1,2,3)); # OUTPUT: «[1 2 3]␤»

Array

multi method append(Array:D: **@values is raw --> Array:D)
multi method append(Array:D: \arg --> Array:D)

주어진 값들을 배열 끝에 더하고 수정된 배열을 돌려줘요. 단 인보컨트 배열이나 펼침(flatten)이 필요한 인자가 lazy라면 예외를 던져요.

push 메서드와 달리 append는 단일 인자 규칙을 따르는데, 이렇게 생각하면 가장 좋아요.

multi method append(Array:D: +values --> Array:D)

즉, itemize되지 않은 Iterable 하나를 단일 인자로 넘기면 append는 그것을 펼치려고 해요.

my @a = <a b c>;
my @b = <d e f>;
@a.append: @b;
say @a.elems;               # OUTPUT: «6␤»
say @a;                     # OUTPUT: «[a b c d e f]␤»

IterationBuffer

method append(IterationBuffer:D: IterationBuffer:D $other --> IterationBuffer:D)

다른 IterationBuffer의 내용물을 이 IterationBuffer의 끝에 더하고, 갱신된 인보컨트를 돌려줘요.

role Buf

method append( $elems )

버퍼의 끝에 이어 붙여요.

my $bú = Buf.new( 1, 1, 2, 3, 5 );
$bú.append(9, 8, 7, 6);
say $bú.raku; # OUTPUT: «Buf.new(1,1,2,3,5,9,8,7,6)␤»

Nil

method append(*@)

Nil(또는 그 파생 타입 객체)에 append하려고 시도했다고 사용자에게 경고해요.

Hash

method append(+@values)

주어진 Pair들이나 짝수 크기 리스트를 Hash에 이어 붙여요. 키가 이미 존재한다면 기존 값을 Array로 바꿔 그 Array에 새 값을 밀어 넣어요. 짝수 크기 리스트와 Pair들의 리스트는 섞어 쓸 수 없다는 점을 주의하세요. 또, 괄호 없는 Pair나 콜론 Pair는 .append의 이름 인자로 취급돼요.

my %h = a => 1;
%h.append('b', 2, 'c', 3);
%h.append( %(d => 4) );
say %h;
# OUTPUT: «{a => 1, b => 2, c => 3, d => 4}␤»
%h.append('a', 2);
# OUTPUT: «{a => [1 2], b => 2, c => 3, d => 4}␤»

주의: push와 비교하면, append는 주어진 값을 펼쳐 넣는 반면 push는 값을 그대로 넣어요.

my %hb = :a[42, ]; %hb.append: "a" => <a b c a>;
say %hb; # OUTPUT: «{a => [42 a b c a]}␤»
my %ha = :a[42, ]; %ha.push: "a" => <a b c a>;
say %ha; # OUTPUT: «{a => [42 (a b c a)]}␤»