Raku의 줄바꿈(newline) 처리
Raku의 줄바꿈(newline) 처리
운영체제마다 줄바꿈을 나타내는 문자나 조합이 달라요. 어떤 시스템은 \n 한 글자로, 또 어떤 시스템은 \r\n 두 글자로 처리하죠. 그래서 모든 언어가 저마다의 규칙을 정해 두는데, Raku는 다음과 같은 규칙을 써요.
본문
- 문자열 리터럴 안의
\n은 유니코드 코드포인트 10을 뜻해요. say가 문자열 끝에 붙여 주는 기본nl-out값도\n이에요.- 출력할 때, Windows에서는 인코더가
\n을\r\n으로 바꿔서 파일·프로세스·터미널로 보내요. 다만 소켓으로 보낼 때는 그렇게 하지 않아요. - 입력할 때는, 어떤 플랫폼이든 디코더가 기본적으로 파일·프로세스·터미널에서 읽은
\r\n을\n으로 정규화해요 (역시 소켓은 제외).
이 두 규칙이 합쳐지면, 소켓 프로그래밍만 제외하면 프로그램 안에서 \r\n을 볼 일이 없어요. 이것은 다른 많은 언어에서도 마찬가지예요.
이 변환을 제어하는 데는 :$translate-nl 이름 붙은 매개변수가 곳곳에서 쓰여요. 예를 들어 Proc::Async.new나 Proc::Async.Supply 같은 곳이죠.
정규식(regex) 언어에서 \n은 논리적 줄바꿈을 뜻하고, \r\n과도 매치돼요.
특정 핸들(handle)의 기본 동작을 바꾸고 싶다면, 그 핸들을 만들 때 :nl-out 속성을 지정하면 돼요.
my $crlf-out = open(IO::Special.new('<STDOUT>'), :nl-out("\\\n\r"));
$*OUT.say: 1; # OUTPUT: «1»
$crlf-out.say: 1; # OUTPUT: «1\␍»
이 예시에서는 IO::Special을 써서 표준 출력을 새 핸들로 복제하면서, 문자열 끝에 백슬래시(\)를 붙이고 이어서 줄바꿈 과 캐리지 리턴 ␍을 덧붙였어요. 그 핸들로 출력하는 모든 내용의 줄 끝에 이 문자들이 붙는 거죠.
정규식에서 \n은 유니코드의 논리적 줄바꿈 정의를 기준으로 삼아요. 그래서 .와도 매치되고 \v나 공백을 포함하는 어떤 클래스와도 매치돼요.