학교는 승자나 패자를 뚜렷이 가리지 않을지 모른다. 어떤 학교에서는 낙제 제도를 아예 없애고 쉽게 가르치고 있다는 것을 잘 안다. 그러나 사회 현실은 이와 다르다는 것을 명심하라.
* luausers 위키에서 퍼온건데, 제 나름대로 덧붙인 것도 있습니다.
Contents
- 1 머리글
- 2 배포
- 3 정보
- 4 Lua 프로그래밍
- 4.1 어떻게 변수들을 선언하는가?
- 4.2 Lua에서 어떻게 타입을 정할 수 있는가?
- 4.3 어떻게 읽기전용 변수들을 만들수 있는가?
- 4.4 객체를 어떻게 복사할 수 있는가?
- 4.5 테이블을 사용해서 집합(set)을 구현하려면 어떻게 하는가?
- 4.6 테이블을 사용해서 어떻게 모듈(module)을 구현하는가?
- 4.7 어떻게 숫자를 문자로 변환하는가?
- 4.8 단어(word), 숫자, 따옴표처리된 문자열등등을 어떻게 읽어들일 수 있는가?
- 4.9 How do I write a self-reproducing program in Lua?
- 4.10 코드 여러줄을 한꺼번에 주석처리하는 방법은?
- 4.11 전역 환경을 저장/복구하려면 어떻게 해야하나?
- 5 Lua를 위한 애드온과 툴
- 6 C 언어 상에서 루아를 사용하기
1 머리글 #
이 문서는 몇가지 Lua에 대한 FAQ의 답을 담고 있다. 아마도 내용은 영원히 '제작중' 상태가 될 것이며, 그러므로 여러분의 것도 우리에게 보내주면 좋겠다. 코드 예제는 Lua 4.0에 따른 업데이트는 하지 않았다. Lua의 일반적인 정보와 Lua 배포본을 얻기 위해서는
루아 공식 홈페이지를 가보도록. *가 표시된 질문은 최근에 업데이트 된 것이다.
루아 공식 홈페이지를 가보도록. *가 표시된 질문은 최근에 업데이트 된 것이다.
2 배포 #
See the download page for instructions on how to get source code and binaries
for Lua. See the mirrors page for a list of all official distribution sites and
mirrors.
2.1 Lua를 빌드하는데 있어서 해야할 일은? #
Lua is implemented in pure ANSI C, and compiles unmodified in all known
platforms. So, all you need to build Lua is an ANSI C compiler (gcc is a popular
one). If you are building Lua under Unix, then you probably have everything you
need and simply typing make should do it. Otherwise, see the next question.
2.2 Lua를 DOS/Windows/Mac에서 어떻게 컴파일 하는가? #
This depends on your compiler. Most compilers in these platforms require that
you create "project" files. In this case, create a project file for each
subdirectory inside src, with the .c files in each directory plus any libraries
that may be needed. The exact lists of which modules should go into which
project are given in the file INSTALL that comes with the current distribution.
If you only want to try Lua, put all .c and .h files from src and its
subdirectories into a single directory and create a project containing all .c
files. I'm sorry but I cannot give more specific instructions. Perhaps we can
distribute project files for popular compilers, specially if someone else
contributes these.
2.4 다음 버젼이 가져올 변경점은? #
만약 호환되지 않을까 생각하고 있다면, 그러지 않아도 된다. 왜냐면 우리는 어떤 비호환성도 발생되는 것을 피하기 위해 모든 노력을 다하고 있기 때문이다.
When incompatibilities are unavoidable, previous code is usually supported unmodified, possibly by building Lua with a suitable compilation flag. In any case, the reference manual contains a list of incompatibilities.
Lua 4.0 was a major new version. While the language itself changed very little (except for the welcome addition of for statements), the C API was completely rewritten and is incompatible with the C API of Lua 3.2. We recommend that you adapt your code to the new API. Until you do, try the compatibility module. The next version will probably bring support for external multithreading and coroutines.
2.5 Lua는 퍼블릭 도메인(public domain)아래에 있나? #
아니다. TeCGraf사가 저작권을 가지고 있다. Nevertheless, Lua is freely available for both academic and commercial purposes at absolutely no cost. See the copyright notice included in the distribution.
2.6 Lua로 부터 확장(상속)된 소프트웨어를 뭐라고 불러야 하나? #
Lua is intended to be used in other people's software, including yours. In most cases, Lua is simply extended with new functions, and this is exactly what Lua was designed for. These new functions adapt Lua for your specific domain. Now, you want to distribute your software and the question arises: "Can I call it Lua, without misrepresenting its origin, as required by the copyright notice?" The answer is the following: If the syntax and semantics of the language (that is, the parser and the virtual machine) remain the same, then the language is still Lua. If you simply add new libraries, or even replace the standard libraries by your own, the language is still the same, and you don't need to give it a completely different name.
Usually, people use some name that has Lua as part of it (CGILua, LuaMan, LuaOrb, etc.), so at the same time it is clear that it uses Lua but that it is not the official Lua distribuition. In other words, it should be very clear that your software uses Lua (or, more specifically, that the language inside your software is Lua), but also it should be clear that your software is not Lua.
If this explanation is still unclear, please contact us.
3 정보 #
Complete information on Lua can be found in its home page and its mirrors. A convenient list of all links related to Lua is available in the links page.
3.3 루아내의 버그를 어떻게 알려주어야 하나? #
Send a message to lua@tecgraf.puc-rio.br. Try also the mailing list: someone else might have come across the same bug and have a fix or an explanation. You may want to search the archives to see whether it has been discussed before.
Before reporting a bug, try to identify a "minimal" program that exhibits the bug. This makes it much easier to reproduce and track down the bug.
3.4 누가 Lua를 사용하는가? #
We maintain a list of projects around the world that use Lua. Please, send us a description of your project; it is much easier to ensure continuing support for developing Lua if we can show our sponsors that Lua is widely used.
4.1 어떻게 변수들을 선언하는가? #
선언할 필요없다 : Lua는 변수선언들을 가지거나 필요로하지 않는다.
But why do you need to declare variables? Some people want to declare variables to protect themselves against typing mistakes. For example, the code
color="red" print(colour)will print nil because color has been mistyped in line 2 and colour has not been defined. To safeguard against these mistakes, and also to spot undefined variables, you can use the getglobal tag method:
function safe_getglobal(x)
local v=rawgetglobal(x)
if v then return v else error("undefined global variable "..x) end
end
settagmethod(tag(nil),"getglobal",safe_getglobal)
With this code in place, any attempt to use an undefined variable (which would have the value nil) will produce an error message.
4.2 Lua에서 어떻게 타입을 정할 수 있는가? #
Lua is a dynamically typed language. This means that variables do not have type, only values do. Since Lua provides access to the type of values (via the type function), you can write your own functions for dynamic typing. Here is one possible scheme.
To check simple types, just use type. The interesting case is checking tables, because we must check that all fields are present and correctly filled, according to pre-defined "templates". So, we need a way to describe the "type" of tables. As mentioned above, a simple type is described by its name, as reported by the type function. Tables are described by "type templates", which are tables that map each field to its required type. Here are some examples useful for user interface toolkits:
TNumber="number"
TPoint={x=TNumber, y=TNumber}
TColor={red=TNumber, blue=TNumber, green=TNumber}
TRectangle={topleft=TPoint, botright=TPoint}
TWindow={title="string", bounds=TRectangle, color=TColor}
Given such descriptions, the following function checks whether a value has a given type:
function checkType(d, t)
if type(t) == "string" then
-- t is the name of a type
return (type(d) == t)
else
-- t is a table, so d must also be a table
if type(d) ~= "table" then
return nil
else
-- d is also a table; check its fields
local i,v = next(t,nil)
while i do
if not checkType(d[i],v) then
return nil
end
i,v = next(t,i)
end
end
end
return 1
end
4.3 어떻게 읽기전용 변수들을 만들수 있는가? #
In large projects, and also in libraries, it is sometimes important to protect some variables so that they cannot be redefined. This is specially useful when several libraries are loaded and you want to make sure they don't redefine each other's functions by accident. You can protect functions in Lua by using the setglobal tag method:
function protect(x)
error("cannot redefine "..x)
end
settagmethod(tag(protect),"setglobal",protect)
This code should be run after all libraries have been loaded.
With this code in place, any attempt to redefine functions will produce an error
message. You can still redefine functions, but you have to do it explicitly:
rawsetglobal("print",nil)
function print (x) ... end
To extend this scheme to other kinds of values, you need to wrap values with
tables, and use both setglobal and getglobal tag methods:
RO=newtag() -- tag for read-only values
function ROvalue(value) -- make a read-only value
local t={value=value}
settag(t,RO)
return t
end
function ROsetglobal(x) -- protects assignment
error(x.." is read-only")
end
function ROgetglobal(x,value) -- get the actual value
return value.value
end
settagmethod(RO,"getglobal",ROgetglobal)
settagmethod(RO,"setglobal",ROsetglobal)
tolerance=ROvalue(0.12) -- make some read-only variables
color=ROvalue("red")
myprint=ROvalue(print)
This scheme only affects variables created with ROvalue, because only those have
the RO tag.
4.4 객체를 어떻게 복사할 수 있는가? #
In Lua, tables are manipulated by reference. So, if the value of x is a table,
then the assignment y=x does not duplicate the table: x and y contain the same
table. (In other words, the values of x and y are references to the same table.)
If you really want to copy a table, you can use the built-in function next, as
in the code below:
function clone(t) -- return a copy of the table t
local new = {} -- create a new table
local i, v = next(t, nil) -- i is an index of t, v = t[i]
while i do
new[i] = v
i, v = next(t, i) -- get next index
end
return new
end
If you want a deep copy, add if type(v)=="table" then v=clone(v) end before
new[i] = v.
4.5 테이블을 사용해서 집합(set)을 구현하려면 어떻게 하는가? #
The best way to implement a set in Lua is to store its elements as indices of a
table. An element is present in a set when the corresponding value in the table
is not nil.
Here are some code snippets for sets:
s={} -- create an empty set
s[x]=1 -- insert element x into set s
s[x]=nil -- remove element x from set s
x_is_present=s[x] -- does s contain x?
Bags are similar to sets, except that elements may appear more than once. Bags
can be implemented similarly to sets, but using the value associated to an
element as its counter. Here are the required code snippets for bags:
-- insert element x into bag s if s[x] then s[x] = s[x]+1 else s[x] = 1 end -- remove element x from set s if s[x] then s[x] = s[x]-1 if s[x] == 0 then s[x] = nil end end
4.6 테이블을 사용해서 어떻게 모듈(module)을 구현하는가? #
One possible way to simulate modules in Lua is to use a table to store the
module functions and variables.
A module should be written as a separate chunk, starting with:
if modulename then return end -- avoid loading the same module twice
modulename = {} -- create a table to represent the module
Since version 3.0, you can also use conditional compilation instead, which is
more efficient:
$ifnot modulename
modulename = {}
...
$end
In the code above, the chunk is still entirely read, but not parsed. A simple
modification using $endinput avoids stops reading as early as possible:
$if modulename
$endinput
$end
modulename = {}
...
Once the module table has been created, functions and variables can be directly
defined with the syntax
function modulename.foo (...) ... end modulename.pi = 3.1415926525
Any code that needs this module has only to execute dofile("filename"), where
filename is the file containing the module. After this, any function can be
called with modulename.foo(...).
If a module function is going to be used many times, the program can give a
local name to it. Because functions are values, it is enough to write localname
= modulename.foo .
Finally, a module may be opened, giving direct access to all its functions and
variables in the global environment, as shown in the code below:
function openModule(mod)
local n, f = next(mod, nil)
while n do
setglobal(n, f)
n, f = next(mod, n)
end
end
Since version 3.1, this is can be expressed more succinctly using foreach:
function openModule(mod) foreach(mod, setglobal) end
4.8 단어(word), 숫자, 따옴표처리된 문자열등등을 어떻게 읽어들일 수 있는가? #
The pattern matching capabilities of read are powerful, but writing patterns is
not for everyone. Here are some useful patterns:
If you want to skip whitespace before reading an item, just prepend "{%s*}" to
your pattern. For instance, "{%s*}%S%S*" skips whitespace and then reads the
next word.
Version 3.2 made this even simpler: you can use "*w" to read a word and "*n" to
read a number. See the reference manual for a complete list of predefined
patterns.
4.9 How do I write a self-reproducing program in Lua? #
Writing a self-reproducing program in any language is fun, but not always easy
because you have to be careful with quotes. In Lua it is easy because there are
alternative quotes:
y = [[ print("y = [[" .. y .. "]]\ndostring(y)") ]]
dostring(y)
For self-reproducing programs in other languages, see the Quine page.
Read also a good explanation of how self-reproducing programs work.
4.10 코드 여러줄을 한꺼번에 주석처리하는 방법은? #
Lua는 "블럭 주석문"이 없다. 그러나 $if nil ... $end을 사용하면 같은 효과를 볼 수 있다. 이것은 C에서 #if 0 ... #endif하는 것과 같다.
4.11 전역 환경을 저장/복구하려면 어떻게 해야하나? #
Try this code:
function save()
local g={}
foreachvar(function (n,v) %g[n]=v end)
return g
end
function restore(g)
foreach(g,setglobal)
end
Since version 3.1, you can do these same, and much more, in C, using lua_open,
lua_close, and lua_setstate.
5 Lua를 위한 애드온과 툴 #
We maintain a list of tools and libraries for Lua. If you would like to
contribute something, please contact us.
5.1 Lua용 디버거가 있는가? #
Lua comes with debugger interface, so that users can write their own monitoring
code (e.g., for a debugger, tracer, or profiler). Some people have used this
interface in unexpected ways, e.g., to control robots. For a sample debugger,
see Ldb.
Version 3.2 contains a debug library, and so you can write monitoring code
directly in Lua.
5.3 Lua용 GUI 툴킷이 있는가? #
Yes, there is tklua, a library for accessing Tk widgets from Lua. There is also
Lua-gnome, a package for building GNOME applications, which includes an
interface to GTK+, the GIMP toolkit.
6.1 C++상에서 Lua를 인터페이싱하려면 어떻게 해야하는가? #
가장 간단한 해결법은 단지 다음과 같이 하면 된다:
extern "C" {
#include "lua.h"
}
For a more sophisticated solution, see lua++, a Lua API for C++.
6.2 Lua로 호출되는 C 함수를 작성하려면? #
You must follow a simple protocol: Get any parameters from Lua with
lua_getparam, make sure they are of the correct type with the appropriate
lua_is... function, convert them with the appropriate lua_get... function, do
something with the converted values, and push the results back to Lua with the
appropriate lua_push... function.
Let's see a practical example and export the getenv function to Lua. For more
examples, see the code that implements the standard library.
The getenv function in C takes a string and returns another string. Its
prototype is
char* getenv(char*);So, the appropriate functions to call are lua_isstring, lua_getstring and lua_pushstring:
void wrap_getenv(void)
{
lua_Object o=lua_getparam(1);
if (lua_isstring(o))
lua_pushstring(getenv(lua_getstring(o)));
else
lua_error("string expected in argument #1 to getenv");
}
Since version 3.0, Lua includes auxiliary functions that simplify writing
wrappers. With these functions, we can write wrap_getenv as:
void wrap_getenv(void)
{
lua_pushstring(getenv(luaL_check_string(1)));
}
After writing the wrapper, you must make it visible to Lua by calling
lua_register("getenv",wrap_getenv). In fact, this is almost exactly what the
standard library does.
6.3 Lua와 같이 내가 좋아하는 C 라이브러리를 사용하려면? #
Just write a wrapper for each function in your library. See question 5.2.
Ok, this is a lot of work (and boring too). Don't despair, today is your lucky
day: toLua is just the tool you need to get 99% of the job done. See also
SWIGLua and lua-swig, two SWIG modules for Lua.
6.4 "스택 사이즈 오버플로우(stack size overflow)"가 무엇인가? #
Except for trivial cases, such as an infinite recursion, you get this message
when you call Lua from C in a loop because arguments and return values
accumulate in Lua's stack. For example, this code will produce "stack size
overflow":
for (i=0;;i++)
{
lua_pushnumber(i);
lua_call("print");
}
The solution is to enclose the code that talks to Lua with calls to
lua_beginblock and lua_endblock:
for (i=0;;i++)
{
lua_beginblock();
lua_pushnumber(i);
lua_call("print");
lua_endblock();
}
To quote from the reference manual: The use of explicit nested blocks is
strongly encouraged.
6.5 C 에서 테이블을 어떻게 traverse하는가? #
Until version 3.0, this was very hard to do. Version 3.1 provides an easy
solution:
lua_pushobject(table);
lua_pushcfunction(f);
lua_call("foreach");
A similar solution can be used for traversing all global variables:
lua_pushcfunction(f);
lua_call("foreachvar");
Version 3.2 introduced two new API functions, lua_next and lua_nextvar, that may
be more convenient.








