8장부터는 컴파일과 실행 및 오류 검사에 대한 이야기를 하고 있다. 이번 8.1 에선 컴파일에 대한 이야기를 하고 있는데, 루아는 인터프리터 언어로써, 실행 중에 코드를 컴파일 할 수 있는 기능을 제공해 주고 있다고 한다.


파일을 컴 파일 할 때는 두개의 명령어가 있는데, 하나는 dofile, 다른 하나는 loadfile 이다. dofile과 달리 loadfile은 오류를 일으켜도 정지하지 않고, 오류 코드를 반환해 준다.


파일을 컴파일 하는 두 컴파일 함수는 무엇이 다를까?

dofile의 경우,

호출 한 번에 파일 내부의 모든 실행을 한번 실행해 준다. 간단한 작업을 한번만 처리 하고자 할 때는 dofile이 유용하다고 한다.

loadfile의 경우,

호출 한번에 파일 내부의 모든 실행을 .. 하지 않는다. 오로지 컴파일만 해 준다. 만약, 한번 컴파일 하고, 여러번 작동해야 할 경우에는, loadfile로 컴파일 한 다음 그 결과를 여러번 호출(함수 처럼)하여, 테스트 할 수 있다.

또한, loadfile은 오류가 발생하면 nil과 함께, 오류 메세지도 반환해 준다. 다중 배정문으로 할당 받아보아 확인해 볼 수 있다. 확인 절차에 따라서 프로그래머에 맞게 오류에 따른 처리를 할 수 있다.

전체적으로 loadfile와 dofile은 동일한 일은 하고 있지만, loadfile 쪽이 더 디테일하게 작동 시킬 수 있기에, 더 부하가 적게 걸리게 할 수 있다.(dofile로 여러번 호출 하는게 아니라, loadfile로 한번 컴파일 하고, 그 결과로 재 호출 한다는 식 된것을 말하는 것이다.)


아까까지, "코드가 정의된 파일"을 컴파일 하는 것을 알아 보았다면, 이번에는 "코드 뭉치"를 컴파일 하는 방법을 알아 볼 것이다. 코드 뭉치를 컴파일 하는 방법으로는 dostring과 loadstring 함수가 있다.


코드를 컴파일 하는 두 컴파일 함수는 무엇이 다를까?

dostring 경우,

아까 설명한것과 동일하다. 즉, 한번 컴파일하고, 한번 실행한다.


loadstring 경우,

좀 할말이 많은데, f = loadstring("i = i + 1"); 이라고 했을 경우, loadstring은 i = i + 1 이라는 익명한수를 리턴하고, f 에 할당 받는데, 이때 f() 라고 했을 경우, i = i + 1 이 실행이 된다.

여기서 중요한것은 이때 i가 전역 변수로 있을 경우에, 전역 변수의 i에 1을 더해 줄 수 있는 것이다. 이것을 통하여, 한가지 사실을 알 수가 있다. 아래 예제 코드를 보자

f() 는 33을 리턴하고, g() 는 2를 리턴 한다. 정적 유효범위에 loadstring은 들어가지 않는다는 것을 알 수 있다. 이것으로 알 수 있는 것은 loadstring 은 전역환경에서 컴파일 하고, g는 지역 환경에서 컴파일 된다는 점이다.

사실, loadstring은 다른 대안(컴파일 관련된 함수)들과 비교했을 때 처리 비용이 꽤 높고, 가독성을 떨어 뜨린다는 단점이 있다. 


그리고 마지막으로 짚고 넘어가야 하는 것이, loadfile함수의 경우, 단지 코드뭉치를 컴파일 하고, 그 결과를 익명함수로 반환해 줄 뿐이라는 것이다. .. 이것은 코드 파일이 인스턴스화 되지 않고, 단지 컴파일만 되었다는 것을 뜻한다. 인스턴스화 하기 위해선 리턴 받은 익명함수를 실행 시키면 된다.

다음 코드를 보자.

function.lua 파일

진짜 실행 파일

이때 print(foo) 는 nil 을 벹어 내는 것을 확인 할 수 있을 것이다.


총평

.. 어렵다. 점점더.

신고
posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요