2015년 4월 20일 월요일

[루아] 루아 메타테이블의 __index 필드

  루아에서는 테이블에 메타테이블(metatable)이라는 것을 붙일 수 있다. 이 메타테이블에 미리 정해진 필드가 채워져 있다면 이것에 의해서 메타테이블이 붙어 있는 원래 테이블의 동작(특성)을 바꿀 수 있다.

  어떤 테이블에 메타테이블을 붙이는 것은 setmetatable()이라는 함수를 사용한다.



          setmetatable(tA, mtA) -- 테이블 tA에 메타테이블 mtA를 첨가

          tB = setmetatable({}, mtA) -- 빈 테이블에 메타테이블을 mtA를 첨가한 것을 tB에 반환
메타테이블에는 정해진 문자열 키값을 갖는 테이블을 필드로 가져야 되는데 이 미리 정해진 문자열 키값들은 __index, __newindex, __call, __tostring, __add 등등이 있다.

  이 중에서 __index 에 대해서만 간단히 설명하면 다음과 같다. 만약 테이블 tA 의 키값으로 요소들을 접근한다고 할 때(tA.nA, tA[1], tA[“FuncA”] 등등) 그 키값이 tA에 없을 때에는 nil 을 반환할 것이다. 하지만 tA에 메타테이블이 연결되어 있다면 그 연결된 메타테이블의 __index 테이블에 등록된 필드를 추가로 검사한다. 예를 들어서



          local tA={x=10}

          print(tA.y) -- "y"라는 키값이 없으므로 nil 이 찍힌다.
          local mt = { __index = { y = 20 } }
          setmetatable(tA, mt)
          print( tA.y ) -- 메타테이블에 있는 20이 찍힌다.



메타테이블의 __index 내부에는 함수도 물론 정의할 수 있다.


          local mtIndex = {}

          function mtIndex:sum()
                    return self.x + self.y — self는 메타테이블이 붙은 원래 테이블
          end
          local tA={x=10, y=20}
          setmetatable( tA, { __index=mtIndex } )

          print( tA:sum() ) -- 30이 찍힌다

          local tB = setmetatable( {x=30, y=40}, {__index = mtIndex} )
          print( tB:sum() ) -- 70이 찍힌다




위의 예제는 간단하지만 이것을 이해했다면 루아(코로나)에서 객체지향을 간단하게나마 구현하는데 응용할 수 있다.

댓글 1개: