Raku의 assuming — 콜러블에 기본 인자 미리 담아두기

Raku의 assuming — 콜러블에 기본 인자 미리 담아두기

같은 함수를 계속 부르면서 일부 인자만 매번 바꾸는 상황, 생각보다 많죠. assuming은 그때 유용한 도구예요. 원래 Callable에 특정 인자를 미리 박아 둔 새 Callable을 만들어 줘요. '커링(currying)의 Raku식 표현'이라고 부를 만해요.

method assuming(Callable:D $self: |primers)

.assuming에 넘긴 인자들이 이미 대응되는 매개변수에 묶여 있는, 같은 동작을 하는 새 함수를 돌려줘요. 나머지 인자만 나중에 받는 함수가 되는 거죠.

my sub slow($n){ my $i = 0; $i++ while $i < $n; $i }

# takes only one parameter and as such wont forward $n
sub bench(&c) { c, now - ENTER now }

say &slow.assuming(10000000).&bench;  # OUTPUT: «(10000000 7.5508834)␤»

인자 개수(arity)가 둘 이상인 서브라면, 'assume'하지 않는 위치 인자 자리에 Whatever 별표 *를 쓰면 돼요.

sub first-and-last($first, $last) {
    say "Name is $first $last";
}

my &surname-smith = &first-and-last.assuming(*, 'Smith');

surname-smith('Joe');  # OUTPUT: «Name is Joe Smith␤»

assume하는 위치 인자와 아닌 위치 인자를 섞는 것도 자유로워요.

sub longer-names($first, $middle, $last, $suffix) {
    say "Name is $first $middle $last $suffix";
}

my &surname-public = &longer-names.assuming(*, *, 'Public', *);

surname-public('Joe', 'Q.', 'Jr.');  # OUTPUT: «Name is Joe Q. Public Jr.␤»

이름 있는 인자(named parameter)도 assume할 수 있어요.

sub foo { say "$^a $^b $:foo $:bar" }
&foo.assuming(13, foo => 42)(24, bar => 72);  # OUTPUT: «13 24 42 72␤»

.assumingMethodBlock을 포함한 모든 종류의 Callable에 쓸 수 있어요. 메서드를 assume할 때는 invocant 자리에 Whatever 별표를 쓰면 돼요.

# We use a Whatever star for the invocant:
my &comber = Str.^lookup('comb').assuming(*, /R\w+/);
say comber 'Raku is awesome! Ruby is great! And Rust is OK too';
# OUTPUT: «(Raku Ruby Rust)␤»

my &learner = {
    "It took me $:months months to learn $^lang"
}.assuming: 'Raku';
say learner months => 2;  # OUTPUT: «It took me 2 months to learn Raku␤»

출처: Raku 공식 문서 — assuming

본문

  • .assuming에 넘긴 인자를 대응 매개변수에 미리 묶은 새 Callable을 돌려줘요.
  • 위치 인자는 assume하지 않는 자리에 *를, 이름 있는 인자는 name => value 형태로 지정해요.
  • MethodBlock을 포함한 모든 Callable에 사용할 수 있어요. 메서드에서는 invocant 자리에 *를 써요.
  • 같은 함수의 일부 인자만 고정해 재사용할 때, 커링처럼 쓰기 좋아요.