티스토리 뷰

프로그래밍/잡탕

[Lua] require, module(..., pakage.seeall)

터프 프로그래머 2012. 1. 22. 12:16
http://lua-users.org/wiki/ModulesTutorial
위 링크에 있는 내용을 좀 번역해봤습니다.
(참고 : lua-user.org/wiki/는 lua 유저들의 wiki 문서입니다. 괜찮은 내용들이 많이 있어서 참고하시는 것도 좋을 것 같습니다.)

Corona를 하는데
local ui = require("ui")
ui.newLabel 등 이러한 문법을 쓰길래 대체 이게 뭐하는 문법인가 싶었는데 이 문서를 봄으로써 해결되었네요.
아래 박스 안에 영어와 그 밑에 한글을 쓰도록 하겠습니다.

Creating and using Modules
모듈을 사용해봅시다. 

Modules can be easily created by creating a file a.lua with the following content:
모듈은 아래 a.lua 파일의 내용처럼 손쉽게 만들 수 있습니다.

module(..., package.seeall);

function foo() print("Hello World!") end

The special table package will be explained later.
저 이상한 pakage 부분은 나중에 설명하겠습니다. 

Now to use this new module just do:
이제 이 새로운 모듈을 사용하기 위해선 이렇게 하면 됩니다. 

> require "a"
> a.foo()
Hello World!

To reload the module is a bit more tricky, because Lua caches already loaded modules. 
모듈을 리로드 하는 것은 조금 까다로운데, 그 이유는 Lua 캐시가 모듈을 미리 로드해놓기 때문입니다.
It is still possible by deleting the entry from the special package.loaded table.
이것은 pakage.loaded 테이블에서 사라지기 전까지 사용이 가능합니다. 

Say we changed foo in a.lua to now print "Hello Module!" instead.
우리가 a.lua의 foo 함수를 print "Hello Module!" 으로 바꿔봤습니다.

If we just continued in the same session as above the following would happen:
우리가 위에서 하던 것 처럼 계속한다면 어떻게 될까요:

> require "a"
> a.foo()
Hello World!

This was not what we wanted.
이것은 우리가 원하는 것이 아닙니다. 

So we reload the module.
그래서 우리는 모듈을 리로드 해야 합니다. 

> package.loaded.a = nil; require "a"
> a.foo()
Hello Module!

Another nice thing is that modules can be named arbitrarily.
또 다른 좋은 점은 모듈은 다른 독단적인 이름이 될 수도 있다는 것입니다.
Say we think that "a" for a module name is a bit short or that reallylongmodulenamesomedamnprogrammerchose is a bit long.
짧은 모듈 이름인 a 대신 reallylongmodule.... 이라는 긴 것을 쓸 수도 있다는 겁니다.

We can then do the following:
우리는 다음처럼도 쓸 수 있습니다.

> require "a"
> bar = a
> bar.foo()
Hello Module!

This works as a module is just a table.
이것은 테이블처럼 구동됩니다. 

Also the call to module via ... allows us to just rename the file to rename the module.
또한 우리는 mudule을 통해 함수 호출을 하는 동안 모듈 파일의 이름을 바꿀 수도 있습니다. 

Privacy in modules

Now consider the following module secret.lua:
이제 다음의 secret.lua를 생각해봅시다. 

module(..., package.seeall);

secret = 42

function reveal_some() return (secret % 2) end

function foo() print("Hello World!", reveal_some()) end

As we will see it is not as secret as we wished:
이것은 우리가 원하는 비밀스러운 것이 아닙니다. (캡슐화??)

> package.loaded.secret=nil require "secret"
> secret.foo()
Hello World!    0
> secret.reveal_some()
> = secret.reveal_some()
0
> = secret.secret
42
> secret.secret=1
> = secret.reveal_some()
1
> secret.foo()
Hello World!    1

Not only can we access the secret value, we can even change it and directly access the reveal_some function. That was not what we wanted!
우리는 secret 값에 직접 접근할 수 있을 뿐만 아니라 바로 바꿔버릴 수도 있고, revea_some 함수를 바로 사용할 수도 있습니다. 이것은 우리가 원하는게 아니죠! 

However using the special "local" keyword, we can limit the scope to the current module only.
하지만 local 키워드를 사용하면, 우리는 이것의 범위를 같은 모듈 내로만 한정시킬 수 있습니다. 

module(..., package.seeall);

local secret=42

local function reveal_some() return (secret % 2) end

function foo() print("Hello World!", reveal_some()) end

And now it really does what we wanted. secret and reveal_some are now only accessible from within the module.
이제 우리가 원하는대로 될 겁니다. secret과 reveal_some은 이제 같은 모듈 안에서만 접근 가능합니다. 

The package table

As already mentioned above Lua uses the special table package to manage modules.
앞에서 말한 특별한 테이블인 package는 모듈들을 관리합니다.

This table has some interesting fields.
이 테이블은 흥미로운 필드들을 갖고 있습니다. 

> table.foreach(package, print)
preload table: 0x806d058
loadlib function: 0x806cbe0
loaded  table: 0x806b930
loaders table: 0x806cc50
cpath   ./?.so;/usr/local/lib/lua/5.1/?.so;/usr/lib/lua/5.1/?.so;/usr/local/lib/l ..
ua/5.1/loadall.soconfig  /
;
?
!
-
path    ./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lu ..
a;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua;/usr/share/lua/5 ..
.1/?.lua;/usr/share/lua/5.1/?/init.lua

Interesting is the package.path, where Lua searches for the files and replaces '?' with the filename. Of course on your (Windows) system this might be different.
흥미로운 것은 '?'과 함께 있는 파일 이름을 찾거나 바꾸기 위한 pakage.path 입니다.
이것은 당신의 OS가 다르다면 다르게 표시될 수 있스빈다. 

package.loaded is a table, where the already loaded modules are stored by name and can be modified as seen above.
package.loaded는 이미 로드된 모듈들이 적재되어 있는 테이블인데 이것을 위에서 본 것 처럼 수정할 수가 있습니다.

Last but not least package.seeall is the special function, which can be given to module to allow inheritance of the global environment.
마지막으로 package.seeall은 특별한 함수인데, 모듈을 상속받을 수 있게 해줍니다.

Note that this has funny side effects as someone can then call for example a.math.sin(x).
(잘 모르겠군요.) 

See Also



발번역이라.... 틀린 부분에 대해 많은 피드백 부탁드립니다..
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday