루아 레퍼런스 매뉴얼 — 표준 라이브러리: 입출력·운영체제·디버그
루아 레퍼런스 매뉴얼 — 표준 라이브러리: 입출력·운영체제·디버그
루아 표준 라이브러리 중 입출력(Input and Output Facilities), 운영체제(Operating System Facilities), **디버그(The Debug Library)**를 다루는 섹션 6.8, 6.9, 6.10을 옮겨왔어요. 입출력은 파일을 읽고 쓰는 io 라이브러리, 운영체제는 시스템 명령 실행이나 환경 변수 같은 OS 기능을 담은 os 라이브러리예요. 디버그는 이름 그대로 스택·로컬 변수·훅(hook)까지 들여다볼 수 있는 debug 라이브러리고요. 셋 다 프로그램이 '혼자 도는 세계' 밖으로 나가 세상과 소통할 때 쓰는 무기라서 실제 코드에서 만날 일이 많아요.
번역할 때 함수 시그니처와 코드, 숫자, 모드 문자열(mode string), 동작 조건은 원문 그대로 보존했어요. 설명만 강사가 옆에서 말해 주는 톤으로 다듬었죠. 특히 io.read의 포맷 문자열이나 file:seek의 whence 값처럼 '정확해야 동작이 달라지는' 부분은 글자 하나도 바꾸지 않았답니다.
출처: Lua 5.4 Reference Manual — §6.8 Input and Output Facilities, §6.9 Operating System Facilities, §6.10 The Debug Library (https://www.lua.org/manual/5.4/manual.html)
본문
6.8 – 입출력 기능 (Input and Output Facilities)
I/O 라이브러리는 파일을 다루는 두 가지 방식을 제공해요. 첫 번째 방식은 **암묵적인 파일 핸들(implicit file handle)**을 쓰는 건데요, 이 경우 기본 입력 파일과 기본 출력 파일을 설정하는 연산이 있고, 모든 입출력 연산이 이 기본 파일들을 대상으로 수행됩니다. 두 번째 방식은 **명시적인 파일 핸들(explicit file handle)**을 쓰는 방식이에요.
암묵적인 핸들을 쓸 때는 모든 연산을 io 테이블이 제공해요. 명시적인 핸들을 쓸 때는 io.open이 파일 핸들을 하나 돌려주고, 그 다음부터는 모든 연산을 그 파일 핸들의 메서드(method)로 호출하게 됩니다.
파일 핸들의 메타테이블(metatable)은 __gc와 __close 메타메서드를 제공하는데, 호출되면 파일을 닫으려고 시도해요.
io 테이블은 또 C 언어에서 흔히 보던 의미 그대로의 미리 정의된 파일 핸들 세 개를 제공해요. 바로 io.stdin, io.stdout, io.stderr예요. I/O 라이브러리는 이 파일들을 닫지 않습니다.
별도의 언급이 없으면, 모든 I/O 함수는 실패했을 때 fail을 반환하고, 두 번째 결과로 오류 메시지, 세 번째 결과로 시스템에 의존하는 오류 코드(error code)를 돌려줘요. 성공하면 false가 아닌 어떤 값을 반환하고요. POSIX가 아닌 시스템에서는 오류 메시지와 오류 코드를 계산하는 과정이 스레드에 안전하지 않을(thread safe) 수 있어요. 그 계산이 전역 C 변수 errno에 의존하기 때문입니다.
io.close ([file])
file:close()와 동일해요. 파일을 지정하지 않으면 기본 출력 파일을 닫습니다.
io.flush ()
io.output():flush()와 동일해요.
io.input ([file])
파일 이름과 함께 호출하면 그 파일을 (텍스트 모드로) 열고, 그 핸들을 기본 입력 파일로 설정해요. 파일 핸들과 함께 호출하면 그 파일 핸들을 그냥 기본 입력 파일로 설정하고요. 인자 없이 호출하면 현재 기본 입력 파일을 반환합니다.
오류가 나면 이 함수는 오류 코드를 반환하는 대신 **오류를 발생(raise)**시켜요.
io.lines ([filename, ···])
주어진 파일 이름을 읽기 모드로 열고, 열린 파일에 대해 file:lines(···)처럼 동작하는 반복자(iterator) 함수를 반환해요. 반복자가 어떤 값도 읽어 오지 못하면 파일을 자동으로 닫습니다.
반복자 함수 말고도 io.lines는 다른 값 세 개를 더 반환해요. 두 개의 nil 값(자리 채움용)과 만들어진 파일 핸들입니다. 그래서 일반 for 루프에서 쓰면, 루프가 오류나 break로 중단돼도 파일이 함께 닫혀요.
io.lines()(파일 이름 없이) 호출은 io.input():lines("l")과 동일합니다. 즉 기본 입력 파일의 줄들을 차례로 순회하는 거죠. 이 경우엔 루프가 끝나도 반복자가 파일을 닫지는 않아요.
파일을 여는 중 오류가 나면 이 함수는 오류 코드 대신 오류를 발생시켜요.
io.open (filename [, mode])
지정된 모드 문자열 mode에 따라 파일을 여는 함수예요. 성공하면 새로운 파일 핸들을 반환합니다.
모드 문자열은 다음 중 하나가 될 수 있어요:
"r": 읽기 모드 (기본값)"w": 쓰기 모드"a": 추가(append) 모드"r+": 갱신(update) 모드, 이전 데이터는 모두 보존"w+": 갱신 모드, 이전 데이터는 모두 지워짐"a+": 추가 갱신 모드, 이전 데이터는 보존되고 쓰기는 파일의 끝에서만 허용
모드 문자열 끝에 'b'를 붙일 수도 있는데, 일부 시스템에서 바이너리 모드로 파일을 열 때 필요해요.
io.output ([file])
io.input과 비슷하지만, 기본 출력 파일에 대해 동작해요.
io.popen (prog [, mode])
이 함수는 시스템에 의존적이라서 모든 플랫폼에서 쓸 수 있는 건 아니에요. 분리된 프로세스(separated process)에서 프로그램 prog를 시작하고, 그 프로그램에서 데이터를 읽거나(mode가 "r"일 때, 기본값) 그 프로그램에 데이터를 쓸 수 있는(mode가 "w"일 때) 파일 핸들을 반환합니다.
io.read (···)
io.input():read(···)와 동일해요.
io.tmpfile ()
성공하면 임시 파일의 핸들을 반환해요. 이 파일은 갱신 모드로 열리고, 프로그램이 끝나면 자동으로 제거됩니다.
io.type (obj)
obj가 유효한 파일 핸들인지 확인해요. obj가 열려 있는 파일 핸들이면 문자열 "file"을, 닫힌 파일 핸들이면 "closed file"을, 파일 핸들이 아니면 fail을 반환합니다.
io.write (···)
io.output():write(···)와 동일해요.
file:close ()
파일을 닫아요. 파일 핸들이 가비지 컬렉션(garbage collection)될 때 파일이 자동으로 닫히긴 하는데, 그 시점은 예측할 수 없어서 그런 자동 처리에 기대면 안 됩니다. io.popen으로 만든 파일 핸들을 닫을 때는 file:close가 os.execute가 반환하는 것과 같은 값을 돌려줘요.
file:flush ()
파일에 기록해 둔 데이터들을 실제로 저장해요.
file:lines (···)
호출할 때마다 주어진 포맷에 따라 파일을 읽는 반복자 함수를 반환해요. 포맷을 주지 않으면 기본값으로 "l"을 사용합니다. 예를 들어 이런 구성을 보면,
for c in file:lines(1) do body end
현재 위치에서 시작해 파일의 모든 문자를 차례로 순회해요. io.lines와 달리 이 함수는 루프가 끝나도 파일을 닫지 않습니다.
file:read (···)
무엇을 읽을지 지정하는 포맷에 따라 파일을 읽어요. 각 포맷에 대해 함수는 읽은 문자를 담은 문자열이나 숫자를 반환하고, 지정된 포맷으로 데이터를 읽지 못하면 fail을 반환해요. (이 경우 함수는 다음 포맷들은 읽지 않습니다.) 인자 없이 호출하면 다음 줄을 읽는 기본 포맷을 사용해요 (아래 참조).
사용할 수 있는 포맷은 이렇습니다:
"n": 숫자 하나를 읽고, 루아의 어휘 규칙(lexical conventions)에 따라 실수(float)나 정수(integer)로 반환해요. (숫자 앞에 공백과 부호가 올 수 있어요.) 이 포맷은 항상 숫자의 유효한 접두사가 되는 가장 긴 입력 시퀀스를 읽어요. 그 접두사가 유효한 숫자를 이루지 못하거나(예: 빈 문자열,"0x","3.4e-") 너무 길면(200자 초과) 그 값을 버리고 포맷이fail을 반환합니다."a": 현재 위치에서 시작해 파일 전체를 읽어요. 파일 끝에서는 빈 문자열을 반환합니다. 이 포맷은 절대 실패하지 않아요."l": 줄의 끝을 건너뛰고 다음 줄을 읽으며, 파일 끝에서는fail을 반환해요. 이게 기본 포맷입니다."L": 줄 끝 문자를 (있으면) 포함해 다음 줄을 읽으며, 파일 끝에서는fail을 반환해요.number: 이 바이트 수만큼의 문자열을 읽고, 파일 끝에서는fail을 반환해요. 숫자가 0이면 아무것도 읽지 않고 빈 문자열을 반환하거나, 파일 끝이면fail을 반환합니다.
"l"과 "L" 포맷은 텍스트 파일에서만 써야 해요.
file:seek ([whence [, offset]])
파일 위치를 설정하고 얻어와요. 위치는 파일의 시작에서 잰 다음처럼, offset에 문자열 whence가 지정하는 기준(base)을 더한 값입니다:
"set": 기준은 위치 0 (파일의 시작)"cur": 기준은 현재 위치"end": 기준은 파일의 끝
성공하면 seek는 파일의 시작에서 바이트 단위로 잰 최종 파일 위치를 반환해요. 실패하면 fail과 오류를 설명하는 문자열을 반환합니다.
whence의 기본값은 "cur", offset의 기본값은 0이에요. 그래서 file:seek()는 위치를 바꾸지 않고 현재 위치만 반환하고, file:seek("set")은 위치를 파일의 시작으로 옮기고 0을 반환하며, file:seek("end")는 위치를 파일의 끝으로 옮기고 그 크기를 반환해요.
file:setvbuf (mode [, size])
파일의 버퍼링(buffering) 모드를 설정해요. 세 가지 모드가 있습니다:
"no": 버퍼링 없음"full": 전체(full) 버퍼링"line": 줄(line) 버퍼링
마지막 두 경우에서 size는 버퍼 크기(바이트 단위)의 힌트예요. 기본값은 적절한 크기입니다.
각 모드의 구체적인 동작은 이식 가능하지(portable) 않아요. 자세한 내용은 여러분 플랫폼의 밑바탕이 되는 ISO C 함수 setvbuf를 확인해 보세요.
file:write (···)
각 인자의 값을 파일에 써요. 인자는 문자열이나 숫자여야 합니다. 성공하면 이 함수가 file을 반환해요.
6.9 – 운영체제 기능 (Operating System Facilities)
이 라이브러리는 os 테이블을 통해 구현돼요.
os.clock ()
프로그램이 사용한 CPU 시간을 초 단위로 근사해서 반환해요. 밑바탕이 되는 ISO C 함수 clock이 반환하는 값이에요.
os.date ([format [, time]])
주어진 포맷 문자열에 따라 형식화된 날짜와 시간을 담은 문자열 또는 테이블을 반환해요.
time 인자가 있으면 그 값을 형식화하고 (이 값에 대한 설명은 os.time 함수 참조), 없으면 현재 시간을 형식화합니다.
format이 '!'로 시작하면 날짜가 **협정 세계시(Coordinated Universal Time, UTC)**로 형식화돼요. 이 선택 문자 다음으로 format이 문자열 "*t"이면 date는 다음 필드들을 가진 테이블을 반환해요: year, month (1–12), day (1–31), hour (0–23), min (0–59), sec (0–61, 윤초 때문), wday (요일, 1–7, 일요일이 1), yday (연중 일수, 1–366), isdst (일광 절약 시간 플래그, 불리언). 마지막 필드 isdst는 정보를 얻을 수 없으면 없을 수도 있어요.
format이 "*t"가 아니면 날짜는 문자열로 반환되며, ISO C 함수 strftime과 같은 규칙으로 형식화됩니다. format을 생략하면 기본값은 "%c"로, 현재 로케일(locale)을 이용해 사람이 읽을 수 있는 날짜·시간 표현을 만들어줘요.
POSIX가 아닌 시스템에서는 C 함수 gmtime과 localtime에 의존하기 때문에 이 함수가 스레드에 안전하지 않을 수 있어요.
os.difftime (t2, t1)
시간 t1에서 시간 t2까지의 차이를 초 단위로 반환해요. (t1, t2는 os.time이 반환하는 값이에요.) POSIX, Windows, 그 외 일부 시스템에서는 이 값이 정확히 t2-t1입니다.
os.execute ([command])
이 함수는 ISO C 함수 system과 동일해요. command를 운영체제 셸(shell)이 실행하도록 넘겨줍니다. 첫 번째 결과는 명령이 성공적으로 종료되면 true, 아니면 fail이에요. 이 첫 결과 다음에는 문자열과 숫자를 반환하는데 다음과 같습니다:
"exit": 명령이 정상적으로 종료됨. 뒤따르는 숫자는 명령의 종료 상태(exit status)"signal": 명령이 시그널(signal)에 의해 종료됨. 뒤따르는 숫자는 명령을 종료시킨 시그널
명령 없이 호출하면 os.execute는 셸을 사용할 수 있으면 true인 불리언을 반환해요.
os.exit ([code [, close]])
ISO C 함수 exit를 호출해서 호스트 프로그램을 종료해요. code가 true면 반환되는 상태는 EXIT_SUCCESS, false면 EXIT_FAILURE, 숫자면 그 숫자가 상태가 됩니다. code의 기본값은 true예요.
선택 인자 close가 true면 함수는 종료하기 전에 루아 상태(Lua state)를 닫아요 (lua_close 참조).
os.getenv (varname)
프로세스 환경 변수 varname의 값을 반환하고, 변수가 정의되어 있지 않으면 fail을 반환해요.
os.remove (filename)
주어진 이름의 파일(POSIX 시스템에서는 빈 디렉터리)을 삭제해요. 실패하면 fail과 오류를 설명하는 문자열, 오류 코드를 반환하고, 성공하면 true를 반환합니다.
os.rename (oldname, newname)
oldname이라는 파일이나 디렉터리의 이름을 newname으로 바꿔요. 실패하면 fail과 오류를 설명하는 문자열, 오류 코드를 반환하고, 성공하면 true를 반환합니다.
os.setlocale (locale [, category])
프로그램의 현재 로케일을 설정해요. locale은 로케일을 지정하는 시스템 의존적 문자열이고, category는 어떤 범주를 바꿀지 설명하는 선택 문자열이에요: "all", "collate", "ctype", "monetary", "numeric", "time". 기본 범주는 "all"입니다. 함수는 새 로케일의 이름을 반환하고, 요청을 수행할 수 없으면 fail을 반환해요.
locale이 빈 문자열이면 현재 로케일이 구현에 정의된 네이티브 로케일(native locale)로 설정되고, "C"이면 표준 C 로케일로 설정됩니다.
첫 인자로 nil을 주고 호출하면 이 함수는 주어진 범주에 대한 현재 로케일의 이름만 반환해요.
C 함수 setlocale에 의존하기 때문에 이 함수는 스레드에 안전하지 않을 수 있어요.
os.time ([table])
인자 없이 호출하면 현재 시간을, table과 함께 호출하면 그 테이블이 지정하는 로컬 날짜·시간을 나타내는 시간 값을 반환해요. 이 테이블은 year, month, day 필드를 가져야 하고, hour(기본값 12), min(기본값 0), sec(기본값 0), isdst(기본값 nil) 필드를 가질 수 있습니다. 다른 필드는 무시돼요. 이 필드들에 대한 설명은 os.date 함수를 참조하세요.
함수가 호출될 때 이 필드들의 값이 유효 범위 안에 있을 필요는 없어요. 예를 들어 sec가 -10이면 다른 필드들이 지정하는 시간의 10초 전을 뜻하고, hour가 1000이면 다른 필드들이 지정하는 시간의 1000시간 후를 뜻합니다.
반환되는 값은 숫자로, 그 의미는 시스템에 따라 달라요. POSIX, Windows, 그 외 일부 시스템에서는 어떤 기준 시각(이른바 "epoch") 이후 지난 초 수를 셉니다. 다른 시스템에서는 의미가 명시되지 않아서, time이 반환한 숫자는 os.date와 os.difftime의 인자로만 쓸 수 있어요.
테이블과 함께 호출하면 os.time은 os.date 함수에 문서화된 모든 필드들을 **정규화(normalize)**해서, 호출 전과 같은 시간을 나타내되 값들은 유효 범위 안에 들어가게 만들기도 해요.
os.tmpname ()
임시 파일에 쓸 수 있는 파일 이름을 담은 문자열을 반환해요. 이 파일은 사용하기 전에 명시적으로 열어야 하고, 더 이상 필요 없을 때 명시적으로 제거해야 합니다.
POSIX 시스템에서는 이 함수가 보안 위험을 피하기 위해 그 이름으로 파일을 실제로 만들기도 해요. (이름을 얻은 뒤 파일을 만들기 전 사이에 다른 사람이 잘못된 권한으로 파일을 만들 수도 있거든요.) 그래도 여러분은 파일을 사용하려면 여전히 열어야 하고, (사용하지 않더라도) 제거해야 해요.
가능하다면 io.tmpfile을 쓰는 게 더 나을 수 있어요. 프로그램이 끝날 때 파일을 자동으로 제거해 주거든요.
6.10 – 디버그 라이브러리 (The Debug Library)
이 라이브러리는 디버그 인터페이스(§4.7)의 기능을 루아 프로그램에서 쓸 수 있게 제공해요. 이 라이브러리를 쓸 때는 주의가 필요해요. 몇몇 함수는 루아 코드에 대한 기본 가정을 깨는 동작을 하는데, 예를 들면 이런 것들이에요: 함수의 로컬 변수는 외부에서 접근할 수 없다, 유저데이터(userdata)의 메타테이블은 루아 코드로 바꿀 수 없다, 루아 프로그램은 크래시하지 않는다. 이런 함수들은 그렇지 않으면 안전하던 코드까지 무너뜨릴 수 있어요. 게다가 이 라이브러리의 일부 함수는 느릴 수 있습니다.
이 라이브러리의 모든 함수는 debug 테이블 안에 제공돼요. 스레드(thread)에 대해 동작하는 모든 함수는 동작 대상을 지정하는 선택 첫 인자를 가지며, 기본값은 항상 현재 스레드입니다.
debug.debug ()
사용자와 대화형(interactive) 모드로 들어가서, 사용자가 입력하는 각 문자열을 실행해요. 간단한 명령과 다른 디버그 기능을 이용해서 사용자는 전역·로컬 변수를 살펴보고, 값을 바꾸고, 표현식을 평가하는 것 등을 할 수 있어요. cont라는 단어만 들어 있는 줄은 이 함수를 끝내서, 호출한 쪽이 실행을 계속하게 합니다.
참고로 debug.debug의 명령들은 어떤 함수 안에 어휘적으로(lexically) 중첩되어 있지 않아서 로컬 변수에 직접 접근할 수 없어요.
debug.gethook ([thread])
스레드의 현재 훅(hook) 설정을 세 값으로 반환해요: 현재 훅 함수, 현재 훅 마스크(mask), debug.sethook 함수가 설정한 현재 훅 카운트. 활성 훅이 없으면 fail을 반환합니다.
debug.getinfo ([thread,] f [, what])
함수에 대한 정보를 담은 테이블을 반환해요. 함수를 직접 줄 수도 있고, f의 값으로 숫자를 줄 수도 있어요. 이 경우 주어진 스레드의 호출 스택(call stack)에서 레벨 f에 있는 함수를 뜻합니다: 레벨 0은 현재 함수(getinfo 자신), 레벨 1은 getinfo를 호출한 함수 (꼬리 호출은 스택에 세지 않아요), 그 다음도 같은 식이에요. f가 활성 함수 개수보다 큰 숫자라면 getinfo는 fail을 반환합니다.
반환되는 테이블은 lua_getinfo가 반환하는 모든 필드를 담을 수 있고, 문자열 what이 어떤 필드를 채울지 설명해요. what의 기본값은 유효 줄(valid lines) 테이블을 제외한 가능한 모든 정보를 얻는 것입니다. 옵션 'f'는 함수 자신을 담은 func라는 필드를 추가하고, 옵션 'L'은 함수가 루아 함수일 경우 유효 줄 테이블을 담은 activelines 필드를 추가해요. 함수에 디버그 정보가 없으면 테이블은 비어 있습니다.
예를 들어 표현식 debug.getinfo(1,"n").name은 합리적인 이름을 찾을 수 있다면 현재 함수의 이름을 반환하고, 표현식 debug.getinfo(print)는 print 함수에 대한 가능한 모든 정보를 담은 테이블을 반환해요.
debug.getlocal ([thread,] f, local)
스택 레벨 f에 있는 함수의, 인덱스 local인 로컬 변수의 이름과 값을 반환해요. 이 함수는 명시적 로컬 변수뿐 아니라 매개변수와 임시 값에도 접근합니다.
첫 번째 매개변수나 로컬 변수가 인덱스 1이고, 그 다음도 코드에 선언된 순서를 따라서 가되, 함수의 현재 스코프에서 활성인 변수만 셉니다. 컴파일 타임 상수는 컴파일러가 최적화해 버렸다면 이 목록에 안 나올 수 있어요. 음수 인덱스는 가변 인자(vararg)를 가리키며, -1이 첫 번째 가변 인자입니다. 주어진 인덱스의 변수가 없으면 fail을 반환하고, 레벨이 범위를 벗어나면 오류를 발생시켜요. (레벨이 유효한지 확인하려면 debug.getinfo를 호출하면 됩니다.)
( (여는 괄호)로 시작하는 변수 이름은 알려진 이름이 없는 변수(루프 제어 변수 같은 내부 변수, 그리고 디버그 정보 없이 저장된 청크(chunk)에서 온 변수)를 나타내요.
인자 f는 함수일 수도 있어요. 그 경우 getlocal은 함수 매개변수의 이름만 반환합니다.
debug.getmetatable (value)
주어진 값의 메타테이블을 반환하고, 메타테이블이 없으면 nil을 반환해요.
debug.getregistry ()
레지스트리(registry) 테이블을 반환해요 (§4.3 참조).
debug.getupvalue (f, up)
함수 f의, 인덱스 up인 업밸류(upvalue)의 이름과 값을 반환해요. 주어진 인덱스의 업밸류가 없으면 fail을 반환합니다.
(루아 함수에서 업밸류는 그 함수가 사용하며, 그래서 그 클로저(closure)에 포함되는 외부 로컬 변수를 뜻합니다.)
C 함수에 대해서는 이 함수가 모든 업밸류의 이름으로 빈 문자열 ""을 사용해요.
? (물음표)라는 변수 이름은 알려진 이름이 없는 변수(디버그 정보 없이 저장된 청크에서 온 변수)를 나타냅니다.
debug.getuservalue (u, n)
유저데이터 u에 연관된 n번째 유저 값(user value)과 불리언을 반환해요. 유저데이터가 그 값을 갖고 있지 않으면 두 번째 값은 false입니다.
debug.sethook ([thread,] hook, mask [, count])
주어진 함수를 디버그 훅으로 설정해요. 문자열 mask와 숫자 count가 훅이 언제 호출될지 설명합니다. 문자열 mask는 다음 문자들의 조합을 가질 수 있으며, 각각 이런 뜻이에요:
'c': 루아가 함수를 호출할 때마다 훅이 호출됨'r': 루아가 함수에서 반환할 때마다 훅이 호출됨'l': 루아가 새 코드 줄에 들어갈 때마다 훅이 호출됨
게다가 count가 0이 아니면 훅은 count개의 명령(instruction)이 실행될 때마다도 호출됩니다.
인자 없이 호출하면 debug.sethook은 훅을 끕니다.
훅이 호출되면, 그 첫 번째 인자는 호출을 유발한 이벤트를 설명하는 문자열이에요: "call", "tail call", "return", "line", "count". line 이벤트에서는 훅이 두 번째 인자로 새 줄 번호도 받아요. 훅 안에서 getinfo를 레벨 2로 호출하면 실행 중인 함수에 대한 더 많은 정보를 얻을 수 있어요 (레벨 0은 getinfo 함수, 레벨 1은 훅 함수입니다).
debug.setlocal ([thread,] level, local, value)
스택 레벨 level에 있는 함수의, 인덱스 local인 로컬 변수에 value를 할당해요. 주어진 인덱스의 로컬 변수가 없으면 fail을 반환하고, 레벨이 범위를 벗어나면 오류를 발생시켜요 (getinfo를 호출해서 레벨이 유효한지 확인할 수 있어요). 그 외에는 로컬 변수의 이름을 반환합니다.
변수 인덱스와 이름에 대한 더 자세한 내용은 debug.getlocal을 참조하세요.
debug.setmetatable (value, table)
주어진 값의 메타테이블을 주어진 테이블(nil일 수 있음)로 설정해요. value를 반환합니다.
debug.setupvalue (f, up, value)
함수 f의, 인덱스 up인 업밸류에 value를 할당해요. 주어진 인덱스의 업밸류가 없으면 fail을 반환하고, 그 외에는 업밸류의 이름을 반환합니다.
업밸류에 대한 더 자세한 내용은 debug.getupvalue를 참조하세요.
debug.setuservalue (udata, value, n)
주어진 값을 udata에 연관된 n번째 유저 값으로 설정해요. udata는 **풀 유저데이터(full userdata)**여야 합니다. udata를 반환하고, 유저데이터가 그 값을 갖고 있지 않으면 fail을 반환해요.
debug.traceback ([thread,] [message [, level]])
message가 있는데 문자열도 nil도 아니면 이 함수는 추가 처리를 하지 않고 message를 그대로 반환해요. 그 외에는 호출 스택의 역추적(traceback)을 담은 문자열을 반환합니다. 선택 인자인 message 문자열은 역추적의 시작 부분에 덧붙여져요. 선택 인자 level 숫자는 역추적을 어느 레벨에서 시작할지 알려줍니다 (기본값은 1, 즉 traceback을 호출한 함수입니다).
debug.upvalueid (f, n)
주어진 함수에서 n번째 번호의 업밸류에 대한 고유 식별자(가벼운 유저데이터(light userdata)로)를 반환해요. 이 고유 식별자들은 서로 다른 클로저들이 업밸류를 공유하는지 프로그램이 확인할 수 있게 해줍니다. 업밸류를 공유하는(즉 같은 외부 로컬 변수에 접근하는) 루아 클로저들은 그 업밸류 인덱스들에 대해 동일한 식별자를 반환해요.
debug.upvaluejoin (f1, n1, f2, n2)
루아 클로저 f1의 n1번째 업밸류가 루아 클로저 f2의 n2번째 업밸류를 가리키도록 만듭니다.
더 알아보기
- 적절한 파일 핸들 vs 명시적 핸들 — 짧고 간단한 처리는
io.read/io.write처럼 기본 파일을 쓰는 방식이 편하고, 파일을 여러 개 다루거나 위치를 옮겨가며 읽을 때는io.open으로 핸들을 받아 메서드로 쓰는 방식이 낫다는 점을 기억해 두세요. io.open의 모드 문자열과file:read의 포맷 —"r"/"w"/"a"에+와b가 붙는 조합, 그리고"n"/"a"/"l"/"L"/숫자포맷은 정확히 외워 두면 파일 다루기가 훨씬 수월해져요.file:seek의"set"/"cur"/"end"도 자주 쓰는 조합이에요.os.time/os.date의 시간 표현 —os.time이 반환하는 숫자의 의미는 시스템마다 달라요. POSIX·Windows에서는 epoch 이후 초 수지만, 그 외 시스템에서는os.date/os.difftime의 인자로만 쓸 수 있다는 점을 알아두세요.- 디버그 라이브러리 사용 시 주의 —
debug는 루아의 기본 가정(로컬 변수 접근 불가, 유저데이터 메타테이블 불변 등)을 깨는 함수들을 담고 있어서, 안전한 코드도 무너뜨릴 수 있어요. 쓰기 전에 반드시 부작용을 고려하세요. - 관련 섹션 — 레지스트리 테이블(§4.3), 디버그 인터페이스(§4.7), 그리고 CLI에서 쓰는
debug.traceback의 실제 동작은 챕터 7 (Lua Standalone)에서 연결돼 있어요.