Introduction
: 루아의 모든 테이블과 유저데이터는 각각 메타테이블이 따로있고, 테이블과 유저데이터를 제외한 다른 타입은 하나의 메타테이블을 공유하는 형태다.
새로운 테이블을 생성하면 항상 메타테이블이 없이 생성된다.
t = {}
print(getmetatable(t)) --> nil
t1 = {}
setmetatable(t, t1)
print(getmetatable(t) == t1) --> true
루아 코드로는 테이블의 메타테이블만 설정할 수 있다. 다른 타입의 메타 테이블을 조작하려면 직접 C 코드를 이용해야 한다.
그리고 테이블은 자신의 메타테이블이 될 수도 있는데, 이때는 자신의 행위를 기술하는 데 사용된다.
1. 산술 메타메서드
: 우선 Set을 구현해보자.
Set = {}
function Set.new (l)
local set = {}
for _, v in ipairs(l) do set[v] = true end
return set
end
function Set.union (a, b)
local res = Set.new{}
for k in pairs(a) do res[k] = true end
for k in pairs(b) do res[k] = true end
return res
end
function Set.intersection (a, b)
local res = Set.new{}
for k in pairs(a) do
res[k] = b[k]
end
return res
end
이제 두 집합의 합집합을 구할 때 덧셈 연산자 "+"를 사용하려 한다. 이를 위해 Set을 표현하는 모든 테이블이 하나의 메타테이블을 공유하도록 할 것이다. 이 메타테이블에서 덧셈 연산자를 어떻게 처리해야 하는지 정의해야 한다.
local mt = {} -- Set에 대한 메타테이블
다음 단계로, Set을 생성하는 Set.new 함수를 수정한다.
function Set.new (l)
local set = {}
setmetatable(set, mt)
for _, v in ipairs(l) do set[v] = true end
return set
end
마지막으로 메타테이블에 덧셈을 처리하는 방법을 설멸하는 메타메서드인 "__add" 추가한다.
mt.__add = Set.union
s1 = Set.new{10, 20, 30, 50}
s2 = Set.new{30, 1}
s3 = s1 + s2
Set.print(s3) --> {1, 10, 20, 30, 50}
동일한 방식으로 곱셈 연산자를 이용해서 교집합을 구하도록 할 수 있다.
mt.__mul = Set.intersection
Set.print((s1 + s2) * s1) --> {10, 20, 30, 50}
메타테이블에는 산술 연산자에 대응하는 필드명이 있다. __add, __mul 외에 뺄셈을 위한 __sub, 나눗셈을 위한 __div, 부정 연산을 위한 __unm, 나머지 연산을 위한 __mod, 지수 연산을 위한 __pow가 있다. 그리고 붙이기 연산을 위한 __concat 필드도 정의할 수 있다.
2. 관계 메타메서드
: 메타테이블을 이용하면 관계 연산자에도 의미를 부여할 수 있다.
- __eq : =
- __lt : < (작음)
- __le : <= (작거나 같음)
위 세개의 관계 연산자는 별도의 메타메서드로 제공되지는 않는다. 대신 루아는 a~=b를 not(a==b)로 표현하듯이 not을 써서 표현할 수 있다.
3. 라이브러리에 정의된 메타메서드
: print() 함수는 인자를 받으면 tostring을 호출해서 출력한다.
위 Set에 다음과 같은 함수가 있다고 해보자.
function Set.tostring (set)
local whole = {}
for e in pairs(set) do
whole[#whole + 1] = e
end
return "{" .. table.concat(whole, ", ") .. "}"
end
위 함수가 있으면 해당 함수를 tostring에 대한 메타메서드로 지정할 수 있다.
mt.__tostring = Set.tostring
s1 = Set.new{10, 4, 5}
print(s1) --> { 4, 5, 10 }
'Lua Script' 카테고리의 다른 글
[Lua] 클래스 (0) | 2018.04.01 |
---|---|
[Lua] 반복자 (0) | 2018.03.28 |
[Lua] 함수의 내부 (0) | 2018.03.28 |
[Lua] 함수 (0) | 2018.03.27 |
[Lua] 문장 (0) | 2018.03.27 |