GnuSmalltalkUsersGuide:BasicChapter 01
- 제 1 장. GNU 스몰토크 사용하기
GNU 스몰토크 사용하기
명령 행 인자
GNU 스몰토크 가상 머신은 아래 명령을 통해 호출할 수 있겠다:
gst [flags...][file...]
SNU 스몰토크를 호출하면 이항 이미지 파일(gst.im이라 불림)이 최신 파일이 되도록 보장할 것이다; 그렇지 않을 경우 8 페이지의 1.2.2절[이미지 로딩하기 또는 새 이미지 생성하기]에 설명된 바와 같이 새 파일을 빌드할 것이다. 첫 번째 호출은 다음과 같은 모양일 것이다:
"Global garbage collection...done"
GNU Smalltalk
ready
st>
하나 또는 그 이상의 파일을 명시할 경우 순서대로 읽히고 실행되며, 마지막 파일에 도달하면 스몰토크가 종료될 것이다. 파일을 명시하지 않을 경우 GNU 스몰토크는 표준 이미지를 읽고, 표준 입력이 단말기(terminal)일 경우 'st>' 프롬프트를 발행한다. 표준 입력으로부터 명시적 읽기(explicit read)를 호출하기 위해서는 파일명에 –를 명시해도 좋다.
'st>' 프롬프트에 있을 때 종료하려면 Ctrl-d 를 이용하거나 ObjectMemory quit을 입력한 후 RET를 입력한다. ObjectMemory snapshot을 이용해 새 이미지를 저장하여 후에 원할 때 재로딩할 수도 있다.
GNU-스타일 옵션에서 일반적으로 --를 명시하면 옵션의 해석을 중단하여 그 다음에 오는 모든 인자는 파일명으로 간주되며 '-'로 시작된다 하더라도 마찬가지다.
긴 플래그와 짧은 플래그 모두 명시 가능하다; 가령 --version은 -v와 정확히 동일하지만 기억하기가 더 수월하다. 짧은 플래그는 한 번에 하나씩, 또는 한꺼번에 명시할 수 있다. 짧은 플래그 또는 짧은 플래그의 그룹은 항시 하나의 대시(dash)로 시작하는데, 이는 그 다음에 파일명 대신 하나의 플래그 또는 플래그 그룹이 따라온다는 것을 의미한다; 긴 플래그는 공백 없이 두 개의 대시로 시작된다.
최근 구현에서 플래그는 파일명과 함께 사용할 수 있지만 플래그를 모두 먼저 명시하는 것과 동일한 효과를 가진다. 다양한 플래그는 아래와 같이 해석된다:
-a
--smalltalk-args
- 그 다음에 오는 모든 옵션은 Smalltalk arguments를 이용해 검색 가능한 스몰토크 코드에 주어질 것으로 취급하면 GNU 스몰토크 자체에는 인자로서 무시한다.
예제:
command line | Options seen by gnu Smalltalk | Smalltalk arguments |
(empty) | (none) | #() |
-Via foo bar | -Vi | #('foo' 'bar') |
-Vai test | -Vi | #('test') |
-Vaq | -Vq | #() |
--verbose -aq -c | --verbose -q | #('-c') |
-c
--core-dump
- 치명적인 신호가 발생하면 종료 전에 core dump를 생성하라. 해당 옵션이 없이는 backtrace만 제공된다.
-D
--declaration-trace
- 클래스명, 메서드명, 그리고 컴파일러가 메서드를 컴파일하면서 생성하는 바이트 코드를 인쇄하라. 플래그가 명령 행에 여러 번 나타나지 않는 한 명령 행에 명시적으로 명명된 파일에만 적용하라.
-E
--execution-trace
- 해석기가 작동하면서 실행되는 바이트 코드를 인쇄하라. 플래그가 명령 행에 여러 번 나타나지 않는 한 사용자가 명시적으로 발행한 (대화식으로 또는 명령 행에 주어진 파일을 통해) 문(statement)에만 적용된다.
--kernel-directory
- 커널 소스 파일이 로딩될 디렉터리를 명시하라. 대부분 GNU Smalltalk 자체를 컴파일 시 사용된다. 스몰토크 코드는 Directory kernel을 이용해 해당 정보를 검색할 수 있다.
--no-user-files
- ~/.st/ 로부터 어떤 파일도 로딩하지 말라 (8 페이지의 1.2.2절 [이미지 로딩하기 또는 새 이미지 생성하기] 참조)[1]. 이는 주로 GNU Smalltalk 자체를 컴파일 시 사용되는데, 설치된 이미지가 소스 트리 내 파일로부터만 빌드되도록 보장하는 역할을 한다.
-K file
--kernel-file file
- 일반적인 방식으로 file을 로딩하되 커널 디렉터리의 부모 디렉터리를 기준으로 검색하라. 부모 디렉터리는 주로 /usr/local/share/smalltalk/ 이다. 위의 –kernel-dir 를 참고하라.
-f
--file
- 아래 두 명령 행은 동일하다:이는 아래와 같이 파일의 시작 시 "sharp-bang" 시퀀스라 불리는 데에 사용되도록 되어 있다.
gst –f file args... gst –q file –a args...
GNU Smalltalk는 첫 행을 주석(comment)로 취급하고, -f 옵션은 인자가 적절하게 스크립트로 전달되도록 보장한다. gst로의 경로의 하드코딩을 피하려면 이를 대신 사용하라[2]:#! /usr/bin/gst -f ...Smalltalk source code...
#! /bin/sh "exec" "gst" "-f" "$0" "$@" ...Smalltalk source code...
-g
--no-gc-messages
- 쓰레기 수집 메시지를 숨긴다.
-h
--help
- 모든 옵션 플래그의 정의부를 포함해 GNU Smalltalk의 명령 행 구문의 간략한 요약본을 인쇄한 후 종료한다.
-i
--rebuild-image
- 항상 새 이미지 파일을 빌드한 후 저장한다; 8 페이지의 1.2.2절 [이미지 로딩하기 또는 새 이미지 생성하기]를 참고한다.
--maybe-rebuild-image
- 이미지 검사를 실행하고 8 페이지의 1.2.2절 [이미지 로딩하기 또는 새 이미지 생성하기]에 설명된 바와 같이 재빌드한다. 이는 –I가 주어지지 않았을 때 기본값이 된다.
-I file
--image-file file
- 기본 위치 대신 file 이라 명명된 이미지를 로딩할 이미지 파일로서 사용하고, file의 디렉터리를 이미지 경로로 설정하라. 해당 옵션은 커널 파일 상에서 파일 일자 확인을 완전히 걸러뛴다; 일반적인 행위를 복구시키려면 --maybe-rebuild-image를 사용한 후, 필요 시 새로 빌드된 이미지를 file로 작성하라.
-q
--quiet
--silent
- GNU Smalltalk가 실행되는 동안에 응답된 값의 인쇄를 최상위 표현식(top-level expression)에서 볼 수 없도록 숨겨라.
-r
--regression-test
- 회귀 검사 시스템에 의해 사용되며, 일반 사용자에게는 해당하지 않을 것이다. 특정 정보의 인쇄를 제어한다.
-S
--snapshot
- 명령 행으로부터 파일을 로딩한 후 이미지를 저장하라. 물론 명령 행에 – (stdin)를 포함시키고 Ctrl-c 를 입력하여 종료할 경우 해당 "스냅숏"은 저장되지 않는다.
-v
--version
- GNU Smalltalk 버전 숫자를 출력한 후 종료하라.
-V
--verbose
- 실행하는 동안 다양한 진단 메시지를 인쇄하라 (각 파일이 로딩될 때마다 파일명을 비롯해 실행 시작에 관한 메시지 혹은 얼마나 많은 바이트 코드가 실행되었는지).
시작 순서
통고: 시작 순서(startup sequence)는 꽤 복잡하다. 개인설정(Customization)에 관심이 없다면 아래 두 절을 건너뛰어도 좋다. 두 절은 명령 행 옵션 -I 을 사용 시에도 적용되지 않지만 --maybe-rebuild-image 를 함께 사용 시에는 적용된다.
해당 절차 도중에 Ctrl-c 를 이용해 언제든 GNU Smalltalk를 취소할 수 있다.
이미지 경로와 커널 경로 선택하기
GNU Smalltalk가 호출되면 먼저 두 개의 경로, "이미지 경로"와 "커널 경로"를 선택한다. 이미지 경로는 두 경로를 연속하여 고려함으로써 설정된다:
- 주어진 경우 --image-file 옵션의 디렉터리 부분;
- SMALLTALK_IMAGE 환경 변수의 값. 단, 그 값이 이미 정의되어 있고 읽을 수 있는 경우; 향후 배포되는 버전에서는 이 단계가 사라질 것이다;
- 바이너리에서 컴파일된 경로 (Unix 시스템에서는 주로 /usr/local/var/lib/smalltalk 또는 /var 아래 유사한 경로). 단, 이미 존재하고 읽을 수 있는 경우;
- 현재 디렉터리. 현재 디렉터리는 이미지가 재빌드되어야 하지만 선택된 디렉터리를 이전 기준에 따라 작성할 수 없는 경우에도 사용된다.
"커널 경로"는 기반 이미지로 컴파일된 스몰토크 코드를 검색하는 디렉터리다. 이런 경우 아래의 가능성이 존재한다:
- --kernel-dir 옵션으로의 인자가 주어진 경우 그 인자;
- SMALLTALK_KERNEL 환경 변수의 값. 단, 그 값이 정의되어 있고 읽을 수 있는 경우; 향후 배포되는 버전에서는 이 단계가 사라질 것이다;
- 바이너리에서 컴파일된 경로 (Unix 시스템에서는 /usr/local/share/smalltalk/kernel 또는 이와 유사한 데이터 파일 경로). 단, 그 경로가 존재하고 읽을 수 있는 경우;
- 이미지 경로에서 kernel라고 명명된 하위 디렉터리.
이미지 로딩하기 또는 새 이미지 생성하기
GNU Smalltalk는 endianness이 다르다 하더라도 대략적으로 동일한 GNU Smalltalk에 의해 호스트 시스템과 크기가 동일한 포인터의 시스템에서 생성된 이미지를 로딩할 수 있다. 예를 들어, GNU Smalltalk 버전이 32-bit PowerPC에서 생성된 이미지는 32-bit x86 gstVM 으로 로딩될 수 있는데, 단, GNU Smalltalk 버전이 충분히 비슷해야 한다. 그러한 이미지는 호환 가능한 이미지라고 부른다. 포인터 크기가 다른 시스템에서 생성된 이미지는 로딩할 수 없다; 가령 우리의 x86 gst 이미지는 x86-64에서 생성된 이미지를 로딩할 수 없다.
-i 플래그가 사용되지 않는 이상 GNU Smalltalk는 먼저 --image-file 에 의해 명명된 파일을 로딩하고 gst를 기본 값으로 한다. 그 값이 발견될 경우 GNU Smalltalk는 이미지가 "오래되지 않도록" 보장하는데, 이는 작성 일자(write date)가 모든 커널 메서드 정의 파일의 작성 일자보다 최신임을 의미한다. 또한 이미지가 위에서 설명한 바와 같이 "호환 가능하도록" 보장한다. 두 가지 검사를 통과하면 GNU Smalltalk는 이미지를 로딩하고 9 페이지의 1.2.3절[이미지가 생성 또는 복구된 이후]을 계속한다.
이것이 실패하면 새 이미지를 생성해야 한다. 앞서 선택한 이미지가 기록 가능(writeable)하지 않을 경우 이제 이미지 경로를 현재 디렉터리로 변경해도 좋다.
이미지를 빌드하기 위해서 GNU Smalltalk는 커널을 구성하는 파일을 하나씩 로딩한다. 파일 목록은 standard_files 변수 내 libgst/lib.c에서 찾을 수 있다. ~/.st/kernel/[3] 에서 자신의 복사본을 대체함으로써 커널 파일을 오버라이드할 수 있다. 예를 들어, ~/.st/kernel/Builtins.st 파일을 생성할 경우 커널 경로에서 Builtins.st 대신 해당 파일이 로딩될 것이다.
GNU Smalltalk는 이미지 개인설정(image customization)과 부분적 버그 수정을 돕기 위해 (이미지가 존재 시) 이미지를 저장하기 전에 두 가지 파일을 더 로딩한다. 첫 번째는 커널 디렉터리의 부모 디렉터리에서 발견할 수 있는 site-pre.st 이다. 사이트에서 사용자가 gst를 실행하면, 커널 디렉터리를 변경하지 않는 한 /usr/local/share/smalltalk/site-pre.st 가 사이트 규모의 개인설정이 가능한 편의 공간을 제공한다. 두 번째 파일은 ~/.st/pre.st 로, 각 사용자의 홈 디렉터리마다 다를 수 있다.[4]
GNU Smalltalk는 다음 단계로 넘어가기 전에 새 메모리 이미지의 스냅숏을 찍어 기존 이미지 파일로 저장하거나, 이것이 불가능할 경우 현재 디렉터리로 저장한다.
이미지가 생성 또는 복원된 후
다음으로 GNU Smalltalk 는 특수 클래스 ObjectMemory 의 (23 페이지, 2.8절 [메모리 접근] 참조) 종속 클래스들에게 returnFromSnapshot 이벤트를 전송한다. 그리고 난 후 ~/.stinit.st 을 이용 가능한 경우 이를 로딩한다.[5]
pre.st 는 pre-snapshot(스냅숏 전) 파일이고 init.st 는 post-image-load initialization(이미지 로딩 후 초기화) 파일이라는 사실을 기억함으로써 pre.st 와 init.st 의 차이를 명심해야 한다.
마지막으로, GNU Smalltalk는 명령 행에 열거된 파일을 로딩하거나 5 페이지 1.1절 [명령 행 인자]에서 설명한 바와 같이 단말기에서 입력에 대한 프롬프트를 로딩한다.
GNU Smalltalk의 구문
GNU Smalltalk가 허용하는 언어는 기본적으로 다른 스몰토크 환경이 허용하는 언어와 동일하며, Smalltalk-80: The Language and Its Implementation 이라고도 알려진 Blue Book 에서 사용되는 구문과 동일하다. Blue Book에서 위쪽 화살표로 표시된 리턴(return) 연산자는 ASCII 탈자 기호인 ^로 매핑된다; 지정 연산자(왼쪽 화살표)는 주로 :=로 표현된다.[6]
사실 GNU Smalltalk의 문법은 전체화면 에디터뿐만 아니라 명령 행 환경 내 시스템과의 상호작용을 단순화하는 것을 목표로 하며, 다른 스몰토크 환경들의 문법과는 약간 다르다.
문(statement)은 하나씩 실행된다; 여러 개의 문은 동일한 지역 변수를 공유하는데, 이러한 변수들은 자동으로 선언된다; 지역 변수를 삭제하려면 . 혹은 새로운 행보다는 문을 종료하라.
a := 42
a!
a
첫 두 개는 42로 인쇄되지만 세 번째는 비초기화되므로 nil로 인쇄된다.
다수의 문을 단일 블록에서 계산하기 위해서는 아래와 같이 eval 블록으로 감싸라.
Eval [
a := 42. a printString
]
중간 결과값은 (정수 42) 를 인쇄하지 않고 최종 결과만 (문자열 '42') 로 인쇄한다.
ObjectMemory quit
이는 시스템을 종료한다. 만일 표준 입력으로부터 문을 읽고 있을 경우 C-d 를 입력하면 스몰토크를 종료할 수 있다.
GNU Smalltalk는 에디터에서 완전한 프로그램을 작성하는 과정을 수월하게 도와주는 세 가지 확장기능을 언어에 제공한다. 하지만 Green Book(Glenn Krasner의 저서 Smalltalk-80: Bits of History, Words of Advice라고도 알려짐)에서 보여주는 file out 구문과도 호환 가능하다.
새 클래스는 이 구문을 이용해 생성된다:
superclass-name subclass: new-class-name [
| instance variables |
pragmas
message-pattern-1 [ statements ]
message-pattern-2 [ statements ]
...
class-variable-1 := expression.
class-variable-2 := expression.
...
]
요약하면 다음과 같다:
- 인스턴스 변수는 메서드 임시 변수와 동일한 구문으로 정의된다.
- 다른 스몰토크들과 달리 메서드 문이 괄호 안에 있다.
- 클래스 변수는 변수 할당과 동일하게 정의된다.
- 프로그램은 클래스 주석, 클래스 범주, 가져온(imported) 명칭 공간, 인덱스된 인스턴스 변수의 모양을 정의한다.기존 클래스에 새 메서드를 정의할 때에도 이와 비슷한 구문이 사용된다.
<comment: ’Class comment’> <category: ’Examples-Intriguing’> <import: SystemExceptions> <shape: #pointer>
class-expression extend [ ... ]
Class-expression은 일반적으로 클래스 객체를 평가(evaluate)하는데, 이는 주로 클래스의 이름에 해당하지만 클래스명 다음에 class 라는 단어가 따라오기도 하며 그럴 경우 잇따른 메서드 정의가 클래스의 인스턴스가 아니라 명명된 클래스 자체에 적용되는 상황을 야기한다.
Number extend [
radiusToArea [
^self squared * Float pi
]
radiusToCircumference [
^self * 2 * Float pi
]
]
Smalltalk 구문과 클래스 라이브러리의 완전한 취급은 포함된 교육 및 클래스 참조에서 찾을 수 있다 (GNU Smalltalk Library Reference 의 "클래스 참조(Class Reference)" 절 참조).
언어의 구현에 관한 정보는 Blue Book에서 더 많이 찾을 수 있다; 관련 부분은 http://users.ipa.net/~dwighth/smalltalk/bluebook/bluebook_imp_toc.html에서 HTML 문서로 이용 가능하다.
검사 도구 실행하기
GNU Smalltalk에는 간단한 회귀 검사 도구(regression test suite)를 제공하는 파일 세트가 딸려 온다.
검사 도구를 실행하려면 최상위 스몰토크 디렉터리로 연결해야 한다.
make check
위를 타이핑하면 검사 도구 파일이 처리되면서 그 이름을 볼 수 있는데, 그것이 전부다. 그 외 다른 출력이 나타나면 문제가 있음을 의미한다.
GNU Smalltalk의 라이센싱
GNU Smalltalk의 여러 부분들은 두 가지 라이센스에 포함된다: 가상 머신과 개발 환경(컴파일러와 브라우저)은 GNU 일반 공중 사용 허가서(General Public License; GPL)에 포함되고, 시스템 클래스 라이브러리는 약소 일반 공중 사용 허가서(Lesser General Public License; LGPL)에 해당된다.
GNU GPL 준수하기
가상 머신에 대한 GPL 라이센싱이란 가상 머신의 모든 파생물(derivative)은 동일한 라이센스를 따라야 함을 의미한다. 다시 말해, GNU Smalltalk 가상 머신을 포함하는 프로그램은 GPL이 아닌 라이센스로 배포하는 것을 엄격하게 금한다. 외부 라이브러리에 대한 바인딩도 포함한다. 예를 들어, Gtk+에 대한 바인딩(binding)는 GPL에 따라 배포되어야 한다.
원리상 GPL은 Smalltalk 프로그램으로 확장되지 않는데, GPL은 가상 머신을 위한 입력 데이터에 불과하기 때문이다. 반면 동적 연결을 통해 GPL을 따르는 바인딩을 이용할 경우 두 가지 부분을 (스몰토크 프로그램과 바인딩) 하나의 프로그램으로 통합할 것이다. 그러므로 우리는 프로젝트와 그 사용자에게 모두 피해를 입힐 수 있는 애매한 영역을 피하도록 GPL에 특별 예외를 추가하였다.
뿐만 아니라 자유 소프트웨어 재단(Free Software Foundation)은 특별 예외로서 GNU LGPL에 따라 배포되는 무료 라이브러리 또는 무료 소프트웨어 프로그램을 GNU Smalltalk를 통합하고, GNU Smalltalk 가상 머신 하에서 실행되는 독립 프로그램과 GNU Smalltalk를 통합할 수 있는 권한을 당신에게 부여한다.
당신은 GNU GPL이 소스 코드의 배포를 요구할 시 해당 코드의 소스 코드를 포함한다는 조건 하에서만 해당 코드의 라이센스와 GNU Smalltalk에 해당하는 GNU GPL의 조건에 따르는 시스템을 복제 및 배포해도 좋다.
수정된 GNU Smalltalk 버전의 제작자는 자신이 수정한 버전에 이와 같은 특별 예외를 꼭 추가시켜야 할 의무는 없다; 즉, 본인의 선택에 따라 달려 있다. GNU 일반 공중 사용 허가서는 해당 예외를 포함하지 않고 수정된 버전을 출시할 권한을 부여한다; 해당 예외를 이용해 예외 항목을 추진하는 수정 버전을 배포시키는 것도 가능하다.
GNU 약소 일반 공중 사용 허가서
GNU Smalltalk에서 실행되는 스몰토크 프로그램은 GNU Smalltalk 클래스 라이브러리 내 시스템 클래스와 연결되어 있다. 따라서 그러한 프로그램들은 GNU 약소 일반 공중 사용 허가서의 조건을 준수해야 한다.[7]
아키텍처에 대한 이러한 라이센스의 해석과 C 언어의 라이센스 해석에 차이가 있다는 사실이 때로는 까다롭다; 스몰토크에서 수용하는 해석은 다음과 같다. 이미지 파일은 객체 파일로 간주할 수 있으므로 라이센스 세부 항목 6a에 해당하는데, 단, 이미지를 로딩하고, 라이브러리를 업그레이드 또는 수정할 수 있고, 수정된 이미지를 저장할 수 있는 권한을 사용자에게 허용해야 한다: 이는 GNU Smalltalk 가상 머신에 내포된 읽고 계산하고 출력하는 반복과정(read-eval-print loop)을 사용자에게 허용 시 가장 간편하게 획득할 수 있다.
다시 말해, 반복과정으로의 접근성을 문서화된 방식으로 남겨두거나 임시 파일을 이미지를 file in한 후 결과를 새 이미지로 저장할 방법을 제공할 경우, 당신은 아래와 같이 보고된 약소 일반 공중 사용 허가서의 세부 항목 6a를 준수한다:
- a) 작업(work)에 적용한 변경 내용을 모두 포함해 컴퓨터 해독이 가능한(machine-readable) 해당 라이브러리 소스 코드를 작업에 포함시켜야 한다 (위의 1절과 2절에 따라 배포되어야 한다); 작업이 라이브러리와 연결된 실행 파일일 경우, 컴퓨터 해독이 가능한 "라이브러리를 사용하는 작업" 전부를 객체 코드와 소스 코드로서 포함시킴으로써 사용자가 라이브러리를 수정한 후 수정된 라이브러리를 포함하는 수정된 실행 파일을 생성하도록 재연결할 수 있도록 한다. (라이브러리 내 정의 파일의 내용을 변경하는 사용자는 수정된 정의를 사용하기 위해 굳이 애플리케이션을 재컴파일할 필요가 없을 것이라고 생각된다.)
향후에는 공유 라이브러리와 유사한 대안 메커니즘이 제공되어 다른 방식으로 GNU LGPL을 준수할 수 있을 것이다.
Notes
- ↑ MS-DOS에서 디렉터리는 _st/ 일 것이다. 홈 디렉터리를 사용하지 않는 OS에서는 현재 디렉터리에서 검색할 것이다.
- ↑ 셸 명령(shell command) 내에 exec 단어는 모두 따옴표로 표기되므로 GNU Smalltalk는 이를 다섯 개의 구분된 주석으로 파싱한다.
- ↑ MS-DOS에서 디렉터리는 _st/kernel이라 불린다. 홈 디렉터리를 사용하지 않는 OS에서는 현재 디렉터리가 검색된다.
- ↑ MS-DOG에서 파일은 _st/pre.st 로 검색되며, 홈 디렉터리를 사용하지 않는 OS에서는 현재 디렉터리에서 pre.st가 검색된다.
- ↑ 위와 동일한 사항이 고려된다. MS-DOS에서 파일은 _st/init.st 이라 불리고, 홈 디렉터리를 사용하지 않는 OS에서는 현재 디렉터리가 검색된다.
- ↑ 지정 연산자에도 두 가지가 있음을 언급해야겠다: _와 :=. 두 가지는 양쪽에 공백이 있다는 가정 하에 서로 바꿔 사용할수 있다. GNU Smalltalk 커널 코드는 오로지 := 형태만 사용하지만, a) 이전 GNU Smalltalk 버전과의 호환성, b) Blue Book에 언급된 지정 연산자와 현재 ASCII 정의 간 올바른 매핑이라는 이유로 _ 또한 지원한다. 옛날에는 (70년대 중반) ASCII 밑줄 문자가 뒤로 화살표(back arrow)로도 인쇄되었고, 많은 단말기들은 그러한 방식으로 표현하였기 때문에 현재에도 사용된다. 하지만 _의 사용은 이식성(portability) 문제를 야기하기도 한다.
- ↑ 물론 GPL 클래스 라이브러리의 사용에 의해 제한될지도 모른다.