library — Tcl 프로시저 표준 라이브러리
library — Tcl 프로시저 표준 라이브러리
Tcl에는 자주 쓰는 기능을 위한 프로시저 라이브러리가 내장되어 있어요. auto_load, auto_execok, auto_mkindex 같은 자동 로딩·자동 실행 관련 프로시저, tcl_findLibrary처럼 확장을 초기화할 때 쓰는 프로시저, 그리고 parray 같은 편의 프로시저까지, 여러 애플리케이션에서 공통으로 쓸 수 있게 만들어진 함수들이에요. 라이브러리 위치는 info library 명령어로 알 수 있어요.
출처: 문서
본문
Tcl에는 자주 필요한 기능을 위한 Tcl 프로시저 라이브러리가 포함되어 있어요. Tcl 라이브러리에 정의된 프로시저들은 여러 애플리케이션에서 쓸 수 있게 만든 범용 함수들이에요. Tcl 라이브러리의 위치는 info library 명령어가 돌려줘요. Tcl 라이브러리 외에도 각 애플리케이션은 보통 자기만의 지원 프로시저 라이브러리를 갖는데, 그 위치는 보통 $app_library 전역 변수 값으로 주어져요(여기서 app은 애플리케이션 이름). 예를 들어 Tk 라이브러리 위치는 tk_library 변수에 저장돼요.
Tcl 라이브러리의 프로시저를 쓰려면 애플리케이션이 라이브러리의 init.tcl 파일을 소스해야 해요. 예를 들어 Tcl 명령어로
source [file join [info library] init.tcl]
처럼요. 애플리케이션의 Tcl_AppInit 프로시저에서 라이브러리 프로시저 Tcl_Init을 호출하면 이 일이 자동으로 이루어져요. init.tcl의 코드는 unknown 프로시저를 정의하고, 다른 프로시저들은 아래 설명하는 자동 로딩 메커니즘으로 필요할 때 로딩되도록 준비해요.
명령 프로시저(Command Procedures)
Tcl 라이브러리에는 다음 프로시저들이 제공돼요.
auto_execok cmd — 이름이 cmd인 실행 파일이나 셸 내장 명령이 있는지 판별해요. 있으면 cmd가 가리키는 실행 파일이나 셸 내장 명령을 실행할 exec에 넘길 인수 리스트를 반환하고, 없으면 빈 문자열을 반환해요. 이 명령은 PATH 환경 변수가 주는 현재 검색 경로의 디렉터리들을 살펴서 cmd라는 실행 파일을 찾아요. Windows에서는 exec가 쓰는 것과 같은 디렉터리와 파일 확장자로 검색이 확장돼요. auto_execok은 이전 검색 정보를 auto_execs라는 배열에 기억해 둬서, 같은 cmd에 대해 다음 호출에서 경로 검색을 피해요. auto_reset 명령어로 auto_execok의 캐시 정보를 잊게 할 수 있어요.
예를 들어 Linux에서 umask 셸 내장 명령을 실행하려면
exec {*}[auto_execok umask]
Windows에서 DIR 셸 내장 명령을 실행하려면
exec {*}[auto_execok dir]
사용자의 PATH에 frobnicate 바이너리가 있는지 알아보려면
set mayFrob [expr {[llength [auto_execok frobnicate]] > 0}]
auto_import pattern — namespace import를 하는 동안 호출되어, pattern이 지정한 가져오는 명령어들이 자동 로딩 라이브러리에 있는지 확인해요. 있으면 import 링크를 만들 수 있도록 그 명령어들이 로드돼요. 자동 로딩 라이브러리에 없으면 auto_import는 아무것도 하지 않아요. 패턴 일치는 namespace import의 일치 규칙에 따라 이루어져요.
이 명령을 직접 호출할 필요는 평소에 없어요.
auto_load cmd — cmd라는 Tcl 명령어의 정의를 로드하려 시도해요. 이를 위해 하나 이상의 디렉터리로 이루어진 자동 로딩 경로를 검색해요. 자동 로딩 경로는 전역 변수 auto_path가 있으면 그 값이에요. auto_path 변수가 없으면 TCLLIBPATH 환경 변수가 있으면 그것을 쓰고, 아니면 자동 로딩 경로는 Tcl 라이브러리 디렉터리 하나뿐이에요. 자동 로딩 경로의 각 디렉터리 안에는 그 디렉터리에 정의된 하나 이상의 명령어와 각 명령어를 로드할 스크립트를 설명하는 tclIndex 파일이 있어야 해요. tclIndex 파일은 auto_mkindex 명령어로 생성해야 해요. cmd가 인덱스 파일에서 발견되면 적절한 스크립트가 평가되어 명령어가 만들어져요. auto_load 명령어는 cmd가 성공적으로 만들어졌으면 1을 반환해요. cmd에 대한 인덱스 항목이 없거나 스크립트가 실제로 cmd를 정의하지 않았으면(예: 인덱스 정보가 낡았을 때) 0을 반환해요. 스크립트를 처리하는 중 오류가 나면 그 오류가 반환돼요. auto_load는 인덱스 정보를 한 번만 읽어서 auto_index 배열에 저장하고, 이후 auto_load 호출은 인덱스 파일을 다시 읽지 않고 배열에서 cmd를 찾아요. 캐시된 인덱스 정보는 auto_reset 명령어로 삭제할 수 있어요. 그러면 다음 auto_load 명령어가 디스크에서 인덱스 데이터베이스를 다시 로드하게 돼요.
이 명령을 직접 호출할 필요는 평소에 없어요. 기본 unknown 핸들러가 그렇게 해줘요.
auto_mkindex dir pattern pattern ... — auto_load에 쓸 인덱스를 생성해요. 이 명령은 dir에서 pattern 인수 중 아무거나와 이름이 일치하는 모든 파일을 검색하고(glob 명령어로 일치 수행), 일치하는 모든 파일에 정의된 모든 Tcl 명령 프로시저의 인덱스를 생성해 dir 안의 tclIndex라는 파일에 저장해요. 패턴을 주지 않으면 *.tcl 패턴이 가정돼요. 예를 들어
auto_mkindex foo *.tcl
는 foo 하위 디렉터리의 모든 .tcl 파일을 읽고 새 인덱스 파일 foo/tclIndex를 생성해요.
auto_mkindex는 Tcl 스크립트를 자식 인터프리터에 소스해서 실행되는 proc·namespace 명령을 감시하는 방식으로 파싱해요. 확장은 (문서화되지 않은) auto_mkindex_parser 패키지를 써서 auto_load 인덱스에 기여할 수 있는 다른 명령을 등록할 수 있어요. 이것이 어떻게 동작하는지 보려면 auto.tcl을 읽어 봐야 할 거예요.
Auto_mkindex_old(auto_mkindex와 같은 구문)는 Tcl 스크립트를 비교적 단순한 방식으로 파싱해요. 어떤 줄이 첫 글자로 proc이라는 단어를 포함하면 프로시저 정의로 가정하고 그 줄의 다음 단어를 프로시저 이름으로 삼아요. 이런 방식으로 나타나지 않는 프로시저 정의(예: proc 앞에 공백이 있는 경우)는 인덱싱되지 않아요. 전역 초기화 코드나 $·*·[·] 같은 특수 문자가 든 프로시저 이름 같은 "위험한" 코드가 스크립트에 있다면, auto_mkindex_old를 쓰는 편이 더 안전해요.
auto_reset — auto_execok과 auto_load가 캐시한 모든 정보를 파괴해요. 이 정보는 다음에 필요할 때 디스크에서 다시 읽혀요. auto_reset은 또한 자동 로딩 인덱스에 나열된 프로시저들을 삭제해서, 다음에 쓰일 때 새 복사본이 로드되도록 해요.
auto_qualify command namespace — command에 대한 정규화된 이름들의 리스트를 계산해요. 이 리스트는 표준 Tcl 인터프리터가 명령어를 찾을 때 따르는 경로를 그대로 반영해요. 먼저 현재 네임스페이스에서, 그다음 전역 네임스페이스에서 찾죠. 따라서 command가 상대적이고 namespace가 ::가 아니면, 반환되는 리스트는 두 원소예요. 하나는 namespace 네임스페이스 안의 명령어처럼 스코프된 command이고, 다른 하나는 전역 네임스페이스 안의 명령어로서의 command예요. 반면 command가 절대적(::로 시작)이거나 namespace가 ::이면, 리스트는 전역 네임스페이스 안의 명령어로서의 command 하나만 담아요.
auto_qualify는 Tcl의 자동 로딩 기능이 pkgIndex.tcl 같은 자동 로딩 인덱스를 만들 때와 런타임에 함수를 실제로 자동 로딩할 때 모두 사용해요.
tcl_findLibrary basename version patch initScript enVarName varName — 확장들이 초기화 중에 쓰는 표준 검색 프로시저예요. 자기 스크립트 라이브러리를 몇몇 표준 디렉터리에서 찾도록 이 프로시저를 호출해요. 라이브러리 디렉터리 이름의 마지막 구성요소는 보통 basenameversion(예: tk8.0)이지만, 빌드 계층 구조에 있을 때는 library일 수 있어요. patch 인수는 사용되지 않아요. initScript 파일은 발견되면 인터프리터에 소스돼요. 이 파일이 발견된 디렉터리는 전역 변수 varName에 저장돼요. 이 변수가 이미 정의되어 있으면(예: 애플리케이션 초기화 중 C 코드가 정의) 검색이 이루어지지 않아요. 그렇지 않으면 이 디렉터리들에서 검색해요: enVarName 환경 변수가 가리키는 디렉터리, Tcl 라이브러리 디렉터리 기준 상대 위치, 표준 설치의 bin·bin/arch 디렉터리 안의 실행 파일 기준 상대 위치, 현재 빌드 트리의 실행 파일 기준 상대 위치, 병렬 빌드 트리의 실행 파일 기준 상대 위치.
parray arrayName ?pattern? — 배열 arrayName의 모든 원소 이름과 값을 표준 출력에 출력해요. pattern을 주면 그 패턴에 일치하는(string match의 일치 규칙 사용) 이름과 그 값만 출력해요. arrayName은 parray 호출자에게 접근 가능한 배열이어야 해요. 지역이든 전역이든 될 수 있어요.
예를 들어 tcl_platform 배열의 내용을 출력하려면:
parray tcl_platform
단어 경계 보조 프로시저(Word Boundary Helpers)
이 프로시저들은 주로 Tk가 내부적으로 사용해요.
tcl_endOfWord str start — 문자열 str에서 시작 인덱스 start 이후에 나타나는 첫 번째 단어-끝 위치의 인덱스를 반환해요. 단어-끝 위치는 시작점 이후 첫 번째 단어 문자 다음에 오는 첫 번째 비-단어 문자로 정의돼요. 시작점 이후에 단어-끝 위치가 더 없으면 -1을 반환해요. Tcl이 어떤 문자를 단어 문자로 보는지에 대한 자세한 내용은 아래 tcl_wordchars·tcl_nonwordchars 설명을 참고해요.
tcl_startOfNextWord str start — 문자열 str에서 시작 인덱스 start 이후에 나타나는 첫 번째 단어-시작 위치의 인덱스를 반환해요. 단어-시작 위치는 비-단어 문자 다음에 오는 첫 번째 단어 문자로 정의돼요. 시작점 이후에 단어-시작 위치가 더 없으면 -1을 반환해요.
예를 들어 문자열에서 각 단어의 시작 인덱스를 플랫폼 규칙대로 출력하려면:
set theString "The quick brown fox"
for {set idx 0} {$idx >= 0} {
set idx [tcl_startOfNextWord $theString $idx]} {
puts "Word start index: $idx"
}
tcl_startOfPreviousWord str start — 문자열 str에서 시작 인덱스 start 이전에 나타나는 첫 번째 단어-시작 위치의 인덱스를 반환해요. 시작점 이전에 단어-시작 위치가 더 없으면 -1을 반환해요.
tcl_wordBreakAfter str start — 문자열 str에서 시작 인덱스 start 이후의 첫 번째 단어 경계를 반환해요. 주어진 문자열에서 시작점 이후에 경계가 더 없으면 -1을 반환해요. 반환되는 인덱스는 경계를 이루는 쌍의 두 번째 문자를 가리켜요.
tcl_wordBreakBefore str start — 문자열 str에서 시작 인덱스 start 이전의 첫 번째 단어 경계를 반환해요. 주어진 문자열에서 시작점 이전에 경계가 더 없으면 -1을 반환해요. 반환되는 인덱스는 경계를 이루는 쌍의 두 번째 문자를 가리켜요.
변수(Variables)
Tcl 라이브러리의 프로시저들이 정의하거나 사용하는 전역 변수는 다음과 같아요. 이들은 크게 두 부류로 나뉘는데, 하나는 알 수 없는 명령어와 패키지를 다루는 것이고, 다른 하나는 무엇이 단어인지를 결정하는 거예요.
자동 로딩 및 패키지 관리 변수
auto_execs — auto_execok이 특정 명령어가 실행 파일로 존재하는지에 대한 정보를 기록하는 데 사용해요. 사용자 코드가 직접 접근하는 건 평소에 유용하지 않아요.
auto_index — auto_load가 디스크에서 읽은 인덱스 정보를 저장하는 데 사용해요. 사용자 코드가 직접 접근하는 건 평소에 유용하지 않아요.
auto_noexec — 어떤 값으로든 설정하면 unknown이 어떤 명령어도 자동 실행하지 않아요.
auto_noload — 어떤 값으로든 설정하면 unknown이 어떤 명령어도 자동 로드하지 않아요.
auto_path — 설정하면 자동 로딩 작업 중 검색할 디렉터리들을 주는 유효한 Tcl 리스트여야 해요(기본 package unknown 핸들러를 쓸 때 패키지 인덱스 파일도 포함). 이 변수는 시작 중에 순서대로 초기화돼요: TCLLIBPATH 환경 변수에 나열된 디렉터리들, tcl_library 전역 변수가 가리키는 디렉터리, tcl_library의 부모 디렉터리, tcl_pkgPath 변수에 나열된 디렉터리들. 파일과 패키지 인덱스를 찾을 추가 위치는 보통 lappend로 이 변수에 추가해야 해요.
예를 들어 실행 중인 스크립트 옆의 lib 디렉터리를 추가하려면:
lappend auto_path [file dirname [info script]]/lib
스크립트가 cd를 쓴다면, auto_path의 항목들이 file normalize되었는지 확인하는 게 좋아요.
env(TCL_LIBRARY) — 설정하면 라이브러리 스크립트를 포함하는 디렉터리 위치를 지정해요(이 변수 값은 tcl_library 변수에 할당되어 info library 명령어가 반환하게 돼요). 설정하지 않으면 기본값이 사용돼요.
이 환경 변수 사용은 테스트 밖에서는 권장되지 않아요. Tcl 설치본은 자기 스크립트 파일이 어디 있는지 이미 알아야 하는데, 그 값이 빌드·설치 중에 박혀 있기 때문이에요.
env(TCLLIBPATH) — 설정하면 자동 로딩 작업 중 검색할 디렉터리들을 주는 유효한 Tcl 리스트여야 해요. 디렉터리는 플랫폼에 관계없이 /를 경로 구분자로 하는 Tcl 형식으로 지정해야 해요. 이 변수는 auto_path 변수를 초기화할 때만 사용돼요.
이 변수의 핵심 결과는 스크립트 사용자가 그 스크립트가 package require로 패키지를 읽을 수 있는 위치 리스트를 지정할 방법을 준다는 거예요. Tcl 스크립트 자체 안에서 설정하는 건 보통 유용하지 않아요. 단, 다른 인터프리터(interp create로 만들거나 스레드·서브프로세스로 띄운 것)가 어디서 로드할지에 영향을 주려는 경우는 제외예요.
단어 경계 결정 변수
이 변수들은 tcl_endOfWord, tcl_startOfNextWord, tcl_startOfPreviousWord, tcl_wordBreakAfter, tcl_wordBreakBefore 명령에서만 사용돼요.
tcl_nonwordchars — 이 변수는 tcl_endOfWord 같은 루틴이 어떤 문자가 단어의 일부인지 판별하는 데 쓰는 정규 표현식을 담아요. 패턴이 문자와 일치하면 그 문자는 비-단어 문자로 간주돼요. Windows에서는 공백·탭·줄바꿈이 비-단어 문자로 간주돼요. Unix에서는 숫자·문자·밑줄을 제외한 모든 것이 비-단어 문자로 간주돼요.
tcl_wordchars — 이 변수는 tcl_endOfWord 같은 루틴이 어떤 문자가 단어의 일부인지 판별하는 데 쓰는 정규 표현식을 담아요. 패턴이 문자와 일치하면 그 문자는 단어 문자로 간주돼요. Windows에서는 공백·탭·줄바꿈이 아닌 모든 문자가 단어를 구성해요. Unix에서는 숫자·문자·밑줄이 단어를 구성해요.
더 알아보기
env,info,re_syntax