Raku에서 나만의 연산자 정의하기
Raku에서 나만의 연산자 정의하기 (Operator tutorial)
Raku에서는 sub 키워드 뒤에 prefix, infix, postfix, circumfix, postcircumfix 중 하나를 붙이고, 콜론 다음에 연산자 이름을 따옴표 구문으로 적어서 연산자를 직접 선언할 수 있어요. (post-)circumfix 연산자는 두 부분을 공백으로 구분해요.
본문
sub hello {
say "Hello, world!";
}
say &hello.^name; # OUTPUT: «Sub»
hello; # OUTPUT: «Hello, world!»
my $s = sub ($a, $b) { $a + $b };
say $s.^name; # OUTPUT: «Sub»
say $s(2, 5); # OUTPUT: «7»
# 더 일반적으로 n개 숫자를 합하는 연산자를 만들 수도 있어요
sub prefix:<Σ>( *@number-list ) {
[+] @number-list
}
say Σ (13, 16, 1); # OUTPUT: «30»
sub infix:<:=:>( $a is rw, $b is rw ) {
($a, $b) = ($b, $a)
}
my ($num, $letter) = ('A', 3);
say $num; # OUTPUT: «A»
say $letter; # OUTPUT: «3»
# 두 변수의 값을 맞바꾸기
$num :=: $letter;
say $num; # OUTPUT: «3»
say $letter; # OUTPUT: «A»
sub postfix:<!>( Int $num where * >= 0 ) { [*] 1..$num }
say 0!; # OUTPUT: «1»
say 5!; # OUTPUT: «120»
sub postfix:<♥>( $a ) { say „I love $a!“ }
42♥; # OUTPUT: «I love 42!»
sub postcircumfix:<⸨ ⸩>( Positional $a, Whatever ) {
say $a[0], '…', $a[*-1]
}
[1,2,3,4]⸨*⸩; # OUTPUT: «1…4»
constant term:<♥> = "♥"; # "love"를 따옴표로 감싸고 싶지 않잖아요?
sub circumfix:<α ω>( $a ) {
say „$a is the beginning and the end.“
};
α♥ω; # OUTPUT: «♥ is the beginning and the end.»
여기서 우선 눈에 띄는 건 Σ처럼 그리스 문자나 ♥처럼 이모지까지 연산자 이름으로 쓸 수 있다는 점이에요. prefix:<Σ>는 여러 숫자를 받아서 전부 더해 주는 연산자를 만들고, infix:<:=:>는 두 변수의 값을 맞바꾸는 연산자예요. postfix:<!>는 팩토리얼(factorial)처럼 뒤에 붙는 연산자이고, postcircumfix:<⸨ ⸩>는 [1,2,3,4]⸨*⸩처럼 값 뒤에 붙어 첫 원소와 마지막 원소를 출력해 줘요.
마지막의 circumfix:<α ω>는 앞뒤로 감싸는 연산자라 α♥ω처럼 쓰면 가운데 값에 대해 동작하는 구조예요.
이 연산자들은 모두 확장 식별자(extended identifier) 문법을 사용해요. 그래서 어떤 유니코드 코드포인트든 연산자 이름으로 쓸 수 있는 거예요.