쓰기
쓰기 (Writing)
값을 출력 포트에 쓰는 함수들과, 그 출력 방식을 제어하는 다양한 파라미터들을 살펴볼게요. write·display·print의 차이와 포맷 문자열을 쓰는 함수들을 함께 익힐 수 있어요.
출처: Racket Reference
본문
procedure
(write datum [out]) → void?
datum : any/c
out : output-port? = (current-output-port)
datum을 out에 써요. 보통 핵심 데이터 타입의 인스턴스를 다시 읽어들일 수 있는 방식으로요. out이 port-write-handler를 통해 연결된 핸들러를 가지면 그 핸들러가 호출돼요. 그렇지 않으면 (write 모드의) 기본 프린터가 다양한 파라미터로 설정된 대로 쓰여요.
기본 프린터에 대한 더 자세한 내용은 The Printer를 참고하세요. 특히 write는 초기 순환 검사 때문에 프린트되는 값의 깊이에 비례하는 메모리를 요구할 수 있다는 점을 기억하세요.
예시를 볼게요:
> (write 'hi)
hi
> (write (lambda (n) n))
#<procedure>
> (define o (open-output-string))
> (write "hello" o)
> (get-output-string o)
"\"hello\""
procedure
(display datum [out]) → void?
datum : any/c
out : output-port? = (current-output-port)
datum을 out에 표시해요. write와 비슷하지만, 보통 바이트·문자 기반 데이터 타입을 원시 바이트나 문자로 쓰는 방식이에요. out이 port-display-handler를 통해 연결된 핸들러를 가지면 그 핸들러가 호출돼요. 그렇지 않으면 (display 모드의) 기본 프린터가 다양한 파라미터로 설정된 대로 쓰여요.
기본 프린터에 대한 더 자세한 내용은 The Printer를 참고하세요. 특히 display는 초기 순환 검사 때문에 프린트되는 값의 깊이에 비례하는 메모리를 요구할 수 있다는 점을 기억하세요.
procedure
(print datum [out quote-depth]) → void?
datum : any/c
out : output-port? = (current-output-port)
quote-depth : (or/c 0 1) = 0
datum을 out에 프린트해요. out이 port-print-handler를 통해 연결된 핸들러를 가지면 그 핸들러가 호출돼요. 그렇지 않으면 global-port-print-handler가 지정한 핸들러가 호출되는데, 기본 핸들러는 print 모드의 기본 프린터를 사용해요.
선택 인자 quote-depth는 print-as-expression 파라미터가 #t로 설정되어 있을 때 프린팅을 조정해요. 그 경우 quote-depth는 datum을 프린트하기 시작할 인용 깊이를 지정해요.
print를 제공하는 이유는 display와 write가 모두 특정 출력 규칙을 가지기 때문이에요. 그 규칙들이 환경이 display와 write 프로시저의 동작을 바꿀 수 있는 방식을 제한하지요. print에는 출력 규칙이 전혀 없다고 가정해서, 환경이 print가 만들어 내는 실제 출력을 어떤 방식으로든 자유롭게 수정할 수 있게 한 거예요.
procedure
(writeln datum [out]) → void?
datum : any/c
out : output-port? = (current-output-port)
(write datum out) 다음에 (newline out)을 실행하는 것과 같아요.
패키지 base의 버전 6.1.1.8에서 추가됨.
procedure
(displayln datum [out]) → void?
datum : any/c
out : output-port? = (current-output-port)
(display datum out) 다음에 (newline out)을 실행하는 것과 같아요. Pascal이나 Java의 println과 비슷하지요.
procedure
(println datum [out quote-depth]) → void?
datum : any/c
out : output-port? = (current-output-port)
quote-depth : (or/c 0 1) = 0
(print datum out quote-depth) 다음에 (newline out)을 실행하는 것과 같아요.
println 함수는 다른 언어의 println과 동등하지 않아요. println은 display보다 write에 가까운 프린팅 규칙을 쓰기 때문이에요. 다른 언어의 println에 더 가까운 대안을 원하면 displayln을 쓰세요.
패키지 base의 버전 6.1.1.8에서 추가됨.
procedure
(fprintf out form v ...) → void?
out : output-port?
form : string?
v : any/c
out에 포맷된 출력을 프린트해요. form은 특별한 포맷 이스케이프를 제외하고는 직접 프린트되는 문자열이에요:
~n또는~%는 줄바꿈 문자를 프린트해요(리터럴 포맷 문자열 안\n과 동등해요).~a또는~A는v들 중 다음 인자를 display해요.~s또는~S는v들 중 다음 인자를 write해요.~v또는~V는v들 중 다음 인자를 print해요.~.‹c›에서‹c›는a,A,s,S,v,V중 하나예요: 기본 핸들러의 display·write·print 출력을(error-print-width)문자로 잘라내고, 자르지 않은 출력이 더 길면 마지막 세 문자로...을 써요.~e또는~E는v들 중 다음 인자를 현재 오류 값 변환 핸들러(error-value->string-handler참고)와 현재 오류 프린팅 폭으로 출력해요.~c또는~C는v들 중 다음 인자를 write-chars해요. 다음 인자가 문자가 아니면exn:fail:contract예외가 발생해요.~b또는~B는v들 중 다음 인자를 2진수로 프린트해요. 다음 인자가 정확한 숫자가 아니면exn:fail:contract예외가 발생해요.~o또는~O는v들 중 다음 인자를 8진수로 프린트해요. 다음 인자가 정확한 숫자가 아니면exn:fail:contract예외가 발생해요.~x또는~X는v들 중 다음 인자를 16진수로 프린트해요. 다음 인자가 정확한 숫자가 아니면exn:fail:contract예외가 발생해요.~~는 물결 표시를 프린트해요.~‹w›에서‹w›는 공백 문자(char-whitespace?참고)예요. 공백이 아닌 문자를 만나거나 두 번째 줄바꿈을 만날 때까지(둘 중 먼저 일어나는 쪽)form의 문자를 건너뛰어요. 모든 플랫폼에서 줄바꿈은#\return,#\newline, 또는#\return바로 뒤에#\newline이 오는 것일 수 있어요.
form 문자열은 위 이스케이프 중 하나가 아닌 ~를 포함하면 안 되며, 포함하면 exn:fail:contract 예외가 발생해요. 포맷 문자열이 공급된 것보다 더 많은 v를 요구하면 exn:fail:contract 예외가 발생해요. 마찬가지로 포맷 문자열이 사용하는 것보다 더 많은 v가 공급되어도 exn:fail:contract 예외가 발생해요.
예시를 볼게요:
> (fprintf (current-output-port)
"~a as a string is ~s.\n"
'(3 4)
"(3 4)")
(3 4) as a string is "(3 4)".
procedure
(printf form v ...) → void?
form : string?
v : any/c
(fprintf (current-output-port) form v ...)과 같아요.
procedure
(eprintf form v ...) → void?
form : string?
v : any/c
(fprintf (current-error-port) form v ...)과 같아요.
procedure
(format form v ...) → string?
form : string?
v : any/c
문자열로 포맷해요. 결과는 다음과 같아요:
(let ([o (open-output-string)])
(fprintf o form v ...)
(get-output-string o))
예시를 볼게요:
> (format "~a as a string is ~s.\n" '(3 4) "(3 4)")
"(3 4) as a string is \"(3 4)\".\n"
parameter
(print-pair-curly-braces) → boolean?
(print-pair-curly-braces on?) → void?
on? : any/c
쌍(pair) 프린팅을 제어하는 파라미터예요. 값이 참이면 쌍이 (와 ) 대신 {와 }를 사용해 프린트돼요. 기본값은 #f예요.
parameter
(print-mpair-curly-braces) → boolean?
(print-mpair-curly-braces on?) → void?
on? : any/c
쌍 프린팅을 제어하는 파라미터예요. 값이 참이면 가변 쌍(mutable pair)이 (와 ) 대신 {와 }를 사용해 프린트돼요. 기본값은 #t예요.
parameter
(print-unreadable) → boolean?
(print-unreadable on?) → void?
on? : any/c
(기본 리더를 사용해) 읽을 수 있는(readable) 형태가 없는 값의 print와 write를 켜거나 끄는 파라미터예요. 여기에는 커스텀 write 프로시저가 있는 구조체(prop:custom-write 참고)도 포함되지만, 인턴되지 않은(uninterned) 심볼과 읽을 수 없는 심볼(인턴된 심볼과 같게 프린트되는)은 포함되지 않아요. 파라미터 값이 #f면 읽을 수 없는 값을 프린트하려는 시도는 exn:fail을 발생시켜요. 파라미터 값의 기본값은 #t예요. 더 자세한 내용은 The Printer를 참고하세요.
parameter
(print-graph) → boolean?
(print-graph on?) → void?
on? : any/c
공유가 있는 데이터를 프린트하는 것을 제어하는 파라미터로, 기본값은 #f예요. 더 자세한 내용은 The Printer를 참고하세요.
parameter
(print-struct) → boolean?
(print-struct on?) → void?
on? : any/c
구조 값을 벡터나 prefab 형태로 프린트하는 것을 제어하는 파라미터로, 기본값은 #t예요. 더 자세한 내용은 The Printer를 참고하세요. 이 파라미터는 커스텀 write 프로시저가 있는 구조체(prop:custom-write 참고)의 프린팅에는 영향을 주지 않아요.
parameter
(print-box) → boolean?
(print-box on?) → void?
on? : any/c
박스(box) 값 프린팅을 제어하는 파라미터로, 기본값은 #t예요. 더 자세한 내용은 Printing Boxes를 참고하세요.
parameter
(print-vector-length) → boolean?
(print-vector-length on?) → void?
on? : any/c
벡터 프린팅을 제어하는 파라미터로, 기본값은 #f예요. 더 자세한 내용은 Printing Vectors를 참고하세요.
parameter
(print-hash-table) → boolean?
(print-hash-table on?) → void?
on? : any/c
해시 테이블 프린팅을 제어하는 파라미터로, 기본값은 #t예요. 더 자세한 내용은 Printing Hash Tables를 참고하세요.
parameter
(print-boolean-long-form) → boolean?
(print-boolean-long-form on?) → void?
on? : any/c
불리언 프린팅을 제어하는 파라미터예요. 파라미터 값이 참이면 #t와 #f가 #true와 #false로 프린트되고, 그렇지 않으면 #t와 #f로 프린트돼요. 기본값은 #f예요.
parameter
(print-reader-abbreviations) → boolean?
(print-reader-abbreviations on?) → void?
on? : any/c
quote, 'quasiquote, 'unquote, 'unquote-splicing, 'syntax, 'quasisyntax, 'unsyntax, 'unsyntax-splicing으로 시작하는 두 요소 리스트의 프린팅을 제어하는 파라미터로, 기본값은 #f예요. 더 자세한 내용은 Printing Pairs and Lists를 참고하세요.
parameter
(print-as-expression) → boolean?
(print-as-expression on?) → void?
on? : any/c
(write나 display와 대비되는) print 모드에서의 프린팅을 제어하는 파라미터로, 기본값은 #t예요. 더 자세한 내용은 The Printer를 참고하세요.
parameter
(print-syntax-width)
→ (or/c +inf.0 0 (and/c exact-integer? (>/c 3)))
(print-syntax-width width) → void?
width : (or/c +inf.0 0 (and/c exact-integer? (>/c 3)))
구문 객체 프린팅을 제어하는 파라미터예요. #<syntax...> 안에서 구문 객체의 datum 형태를 보여주는 데 최대 width 문자만 사용해요 (구문 객체의 소스 위치 뒤에요). 프린트된 형태가 width 문자보다 길면 마지막 세 문자로 ...을 써요. width 값이 0이면 datum을 전혀 보여주지 않아요.
parameter
(print-value-columns)
→ (or/c +inf.0 (and/c exact-integer? (>/c 5)))
(print-value-columns columns) → void?
columns : (or/c +inf.0 (and/c exact-integer? (>/c 5)))
print로 값을 프린트할 때 사용해야 할 열(column) 수에 대한 권장값을 담는 파라미터예요. print가 존중할 수도, 존중하지 않을 수도 있어요. 현재 print의 기본 핸들러는 존중하지 않아요. 값의 pretty-printing을 어떤 형태로든 사용하는 REPL이 이 파라미터를 존중할 것으로 기대돼요.
패키지 base의 버전 8.0.0.13에서 추가됨.
parameter
(current-write-relative-directory)
→
(or/c (and/c path? complete-path?)
(cons/c (and/c path? complete-path?)
(and/c path? complete-path?))
#f)
(current-write-relative-directory path) → void?
path :
(or/c (and/c path-string? complete-path?)
(cons/c (and/c path-string? complete-path?)
(and/c path-string? complete-path?))
#f)
경로 이름 리터럴을 포함하는 컴파일된 코드를 쓸 때(Printing Compiled Code 참고), 프로시저 이름의 소스 위치 경로 이름을 포함해서 사용되는 파라미터예요. 파라미터 값이 경로면, 구문적으로 path를 확장하는 경로는 상대 경로로 변환돼요. 결과 컴파일 코드를 읽을 때 상대 경로는 current-load-relative-directory 파라미터를 사용해 완전한 경로로 다시 변환돼요(#f가 아니면; 그렇지 않으면 경로는 상대로 남겨져요). 파라미터 값이 (cons rel-to-path base-path)면, 구문적으로 base-path를 확장하는 경로는 rel-to-path에 대해 상대적으로 변환돼요. rel-to-path는 base-path를 확장해야 하며, 그 경우 'up 경로 요소(build-path의 의미로)를 사용해 경로를 rel-to-path에 대해 상대적으로 만들 수 있어요.
procedure
(port-write-handler out) → (any/c output-port? . -> . any)
out : output-port?
(port-write-handler out proc) → void?
out : output-port?
proc : (any/c output-port? . -> . any)
procedure
(port-display-handler out) → (any/c output-port? . -> . any)
out : output-port?
(port-display-handler out proc) → void?
out : output-port?
proc : (any/c output-port? . -> . any)
procedure
(port-print-handler out)
→ ((any/c output-port?) ((or/c 0 1)) . ->* . any)
out : output-port?
(port-print-handler out proc) → void?
out : output-port?
proc : (any/c output-port? . -> . any)
out의 포트 write 핸들러, 포트 display 핸들러, 또는 포트 print 핸들러를 가져오거나 설정해요. write, display, print(각각)이 포트에 적용될 때 이 핸들러가 포트에 출력하기 위해 호출돼요. 각 핸들러는 두 인자를 받아야 해요: 프린트할 값과 대상 포트. 핸들러의 반환 값은 무시돼요.
포트 print 핸들러는 선택적으로 세 번째 인자를 받는데, 이는 print의 선택 세 번째 인자에 대응해요. port-print-handler에 주어진 프로시저가 세 번째 인자를 받지 않으면, 선택 세 번째 인자를 버리는 프로시저로 감싸져요.
기본 포트 display·write 핸들러는 Racket 내장 프린터로 Racket 표현식을 프린트해요(The Printer 참고). 기본 print 핸들러는 전역 포트 print 핸들러(global-port-print-handler 파라미터의 값)를 호출해요. 기본 전역 포트 print 핸들러는 기본 write 핸들러와 같아요.
procedure
(global-port-print-handler)
→ (->* (any/c output-port?) ((or/c 0 1)) any)
(global-port-print-handler proc) → void?
proc :
(or/c (->* (any/c output-port?) ((or/c 0 1)) any)
(any/c output-port? . -> . any))
전역 포트 print 핸들러를 결정하는 파라미터예요. 이 핸들러는 기본 포트 print 핸들러(port-print-handler 참고)가 값을 포트에 프린트하기 위해 호출해요. 기본값은 default-global-port-print-handler와 동등해요.
전역 포트 print 핸들러는 선택적으로 세 번째 인자를 받는데, 이는 print의 선택 세 번째 인자에 대응해요. global-port-print-handler에 주어진 프로시저가 세 번째 인자를 받지 않으면, 선택 세 번째 인자를 버리는 프로시저로 감싸져요.
procedure
(default-global-port-print-handler v
out
[print-depth]) → void?
v : any/c
out : output-port?
print-depth : (or/c 0 1) = 0
내장 프린터(The Printer 참고)를 print 모드로 사용해 v를 out에 프린트해요.
패키지 base의 버전 8.8.0.6에서 추가됨.