본문 바로가기
  • hazard_dev@__
  • hazard_dev@__
Lua

LUA스크립트 눈 깜짝할 새 배우기@#3

by Hazard3_o00sung 2020. 11. 25.
728x90

달을 상징하는 아름다운 언어 루아입니다.

1. 메타 테이블 및 메타 함수

루아를 완벽하고 강력하게 사용하기 위해선 메타 테이블을 사용해야만 합니다! 루아에서 테이블은 강력한 자료구조형으로 키와 값의 쌍 및 관련 메타함수를 사용해서 테이블 간 연결된 동작을 수정하고 정의하는데 도움이 되는 형태입니다. 

 

  • 테이블의 연산자에 대한 기능 변경 추가가 가능함
  • 메타 테이블에서 _index를 사용해 테입르에서 키를 사용할 수 없는 경우 메타 테이블을 손쉽게 순회할 수 있음

메타테이블을 처리하는데 도움이 되는 아주 유용한 내장함수들이 존재합니다! 간략하게 보고 넘어가야합니다!

setmetatable(table, metatable) 테이블에 대한 메타 테이블을 설정하는데 사용
getmetatable(table) 테이블의 메타 테이블을 가져오는데 사용

우선 코드로 임의의 테이블을 다른 테이블의 메타 테이블로 설정하는 방법을 살펴보아야 합니다.

1
2
3
= {}
t1 = {}
setmetatable(t, t1)
cs

1-1. _index

아래는 테이블에서 사용할 수 없는 경우 메타 테이블을 조회하기 위한 간단한 메타 테이블의 예제입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
mytable = setmetatable({},{})
mytable = setmetatable({keyName = "value1"}, {
   __index = function(mytable, key)
    
      if key == "key2" then
         return "metatablevalue"
      else
         return mytable[key]
      end
   end
})
 
print(mytable.keyName,mytable.key2)
cs

코드의 복잡도가 이전 포스팅들에 비해서 올라간 것을 볼 수 있지만 사실 아주 아주 간단합니다. 제가 제 블로그에 올리는 글들은 또한, 천천히 코드를 음미하시라는 말을 전해드리고 싶습니다. 

 

  1. 우선 mytable은 메타 테이블로 설정된 것을 확인할 수 있습니다.
  2. 메타 테이블은 우리가 메타함수라 부르는 _index를 mytable안에 포함해 정의합니다.
  3. 메타 함수는 key2인덱스를 찾는 간단한 작업을 수행하며, 탐색에 성공하면 "metavtablevalue"를 반환하고, 그렇지 않으면 해당 인덱스에 대한 값을 반환하며 종료합니다.

물론 이보다 더 단순하게 프로그램화 할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mytable = setmetatable({},{})
mytable = setmetatable({keyName = "value1"}, {
   __index = function(mytable, key)
    
      if key == "key2" then
         return "metatablevalue"
      else
         return mytable[key]
      end
   end
})
 
mytable2 = setmetatable({key1 = "value1"},
    {__index = {key2 = "metavalue"
})
 
print(mytable2.key1, mytable2.key2)
cs

위의 mytable2로 선언해서 사용해도 같은 결과입니다. 본인의 입맛에 맞는 방식으로 선언해 사용하면 아무 문제 없습니다!!

1-2.__newindex

__newindex를 메타 테이블에 추가 할 때 테이블에서 키를 사용할 수 없는 경우 새 키의 동작은 정의된 메타 함수에 의해 정의됩니다! 메인 테이블에서 인덱스를 사용할 수 없을 때 위와 같은 키워드를 활용해 메타 테이블의 인덱스를 설정할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
mymetatable = {}
mytable = setmetatable({key1 = "value1"}, {__newindex = mymetatable})
 
print(mytable.key1)
 
mytable.newKey = "new Value2"
print(mytable.newKey, mymetatable.newKey)
 
mytable.key1 = "new Value1"
print(mytable.key1, mymetatable.key1)
cs

이때 출력결과로는,

RESULT >

value1

nil new Value2

new Value1 nil

 

새로운 인덱스에 접근할 수 없을 때 mytable에 newKey라는 쌍을 추가하게 될시 새로 추가된 메타테이블인 mymetatable에 할당되었다는 것을 알 수 있습니다!

1-3. 연산자 결합 

루아에서의 연산자와 테이블 간 결합은 C++에서의 연산자 오버로딩과 비슷한 역할을 합니다. 예를 들어 '+'연산자를 사용해서 두개의 테이블을 연결하는 예제 코드를 보게되면,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mytable = setmetatable({ 123 }, {
   __add = function(mytable, newtable)
    
      for i = 1, table.maxn(newtable) do
         table.insert(mytable, table.maxn(mytable)+1,newtable[i])
      end
      return mytable
   end
})
 
secondtable = {4,5,6}
 
mytable = mytable + secondtable
 
for k,v in ipairs(mytable) do
   print(k,v)
end
cs

__add라는 키워드는 '+'의 오버로딩을 의미합니다. 새로들어올 newtable과의 결합을 앞서 배운 for반복문을 통해서 inserting하고 있는 것을 확인할 수 있습니다. 그렇기 때문에 13번줄의 '+'연산은 결합으로서 완성됩니다!

이때 연산자를 오버로딩하기 위한 메서드의 목록을 알려드리면,

__add '+'의 역할을 수행하며 결합을 진행함
__sub '-'의 역할을 수행합니다
__mul '*'의 역할을 수행합니다
__div '/'의 역할을 수행합니다
__mod '%'의 역할을 수행합니다
__unm '-'의 역할을 수행하지만 __sub와 다른 것은 unary한 동작을 하며 음수로 변환하는 역할을 합니다
__concat '..'의 역할을 수행하며 문자열 연결등에 쓰입니다. C언어에서는 문자열 결합과 비슷한 이름이니 익숙할 것이라 생각이 드네요
__eq '=='의 역할을 수행합니다
__lt '<'의 역할을 수행합니다
__le '<='의 역할을 수행합니다

이정도를 알아두시면 루아를 사용하는데 아무런 무리없이 사용하실 수 있을것이라 예상되네요!

 

1.4 __call

함수 호출의 동작 추가는 __call 키워드를 사용해 수행되며, 전달 된 테이블이 있는 기본 테이블의 합계를 반환하는 간단한 코드를 확인해 보겠습니다!

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mytable = setmetatable({10}, {
   __call = function(mytable, newtable)
   sum = 0
    
      for i = 1, table.maxn(mytable) do
         sum = sum + mytable[i]
      end
    
      for i = 1, table.maxn(newtable) do
         sum = sum + newtable[i]
      end
    
      return sum
   end
})
 
newtable = {10,20,30}
print(mytable(newtable))
cs

이제 이런 루아의 형태가 점점 자연스러워지고 계신다면, 성공입니다!! 함수를 생성 및 호출 할 수 있습니다. 테이블이라는 자료구조로 그치는 것이 아닌 메타의 형태로 함수도 담을 수 있는 루아의 메타테이블입니다!!! 

 

사실 이정도면 루아를 사용하는데 있어서 그렇게 어려움 없이 사용할 수 있습니다. 확장언어로 간단하게 사용되는 언어이기 때문에 한번 훑고 넘어가셔도 좋지만, 제 블로그 포스팅을 다 읽으신 뒤에도 부족하시다면, lua의 문서를 읽어보시는 것을 추천드립니다!!!

 

감사합니다!! 댓글로 피드백 환영합니다!

 

1부터 보시고 싶으신 분은 아래 링크 !!!

hazarddev.tistory.com/34

 

LUA스크립트 눈 깜짝할 새 배우기@#1

루아 @ 달을 의미하는 포르투갈의 단어인 루아 스크립트 언어는 가벼운 명령형/ 절처형 언어로, 확장 언어의 사용 목적으로 설계된 언어입니다. 루아가 제시하는 패러다임과 체계를 아래 테이블

hazarddev.tistory.com

 

728x90

'Lua' 카테고리의 다른 글

LUA스크립트 눈 깜짝할 새 배우기@#2  (1) 2020.11.24
LUA스크립트 눈 깜짝할 새 배우기@#1  (5) 2020.11.24

댓글