일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 다형성
- 언리얼
- more effective c++
- 스마트 포인터
- c++
- effective stl
- 게임
- 상속
- 비교 함수 객체
- 오블완
- 티스토리챌린지
- UE4
- implicit conversion
- 참조자
- operator new
- Smart Pointer
- reference
- 영화 리뷰
- 반복자
- lua
- 예외
- resource management class
- Effective c++
- 메타테이블
- exception
- Vector
- virtual function
- 암시적 변환
- 영화
- 루아
- Today
- Total
스토리텔링 개발자
[Lua] __newindex 로 할당 로직 재정의 본문
개요
테이블에 값 할당을 커스텀할 때 무심코 실수할만한 부분이 있어 정리했습니다.
__newindex란?
테이블에 값 할당을 시도할 시 해당 키가 존재하지 않는다면 동작하는 메타테이블의 재선언 가능입니다.
[Lua] 메타 테이블(Metatable)
문제점
위 정의에서 문제가 되는 부분은 '해당 키가 존재하지 않는다면' 입니다.
정리하자면 해당 키 값으로 할당된 적이 없을때만 __newindex의 로직이 실행됩니다.
아래의 예시를 보시죠.
isVisible 키에 할당 시 내부 inner의 isVisible에도 함께 할당시키고 싶은 상황입니다.
보기 쉽게 정리하면 아래와 같습니다.
1. 'isVisible 할당'이라고 출력
2. 해당 테이블에 isVisible 할당
3. 해당 테이블 내의 inner 테이블에도 isVisible 할당
setmetatable(instance, {
__newindex = function(t, k, v)
if k == "isVisible" then
print("isVisible 할당");
rawset(t, "isVisible", v); -- 이 부분이 문제
if t.inner then
t.inner.isVisible = v;
end
return;
end
rawset(t, k, v);
end
});
위와 같이 처리하면 아래와 같은 현상이 발생합니다.
instance.isVisible = true;
instance.isVisible = false;
결과창
isVisible 할당
결과창을 보면 알 수 있다시피 두 번의 할당을 시도했지만, 할당은 단 한번만 일어났습니다.
이는 __newindex가 바로 '해당 키값이 없을때만' 동작하기 때문입니다.
해결
해결 방법은 간단합니다.
setmetatable(instance, {
__newindex = function(t, k, v)
if k == "isVisible" then
print("isVisible 할당");
rawset(t, "saveVisible", v); -- 이 부분의 키값을 isVisible에서 saveVisible로 수정
if t.inner then
t.inner.isVisible = v;
end
return;
end
rawset(t, k, v);
end,
__index = function(t, k)
if k == "isVisible" then -- isVisible로 saveVisible 값을 가져오기 위해
print("isVisible 가져오기");
k = "saveVisible";
end
return rawget(t, k);
end
});
__newindex에서 다른 키로 rawset을 해버립니다.
즉, 원래 의도했던 isVisible 키는 늘 비어있게 만드는 방법입니다.
위의 방법을 사용하면 정확히 원래 사용하고자 했던 방식으로 사용할 수 있습니다.
instance.isVisible = true;
instance.isVisible = false;
결과창
isVisible 할당
isVisible 할당
결론
__newindex는 새로운 할당을 할 때만 호출됩니다.
그러므로 '동일한 키에 할당하는 상황'을 캐치하려면 편법이 필요합니다.
__newindex 내에서 키 값을 다르게 할당해서 늘 그 키가 비어있도록 처리한다면,
__index도 함께 선언해주어서 키의 값을 가져오고 할당하는 부분을 통일성있게 해줘야 합니다.
'개발 > Lua' 카테고리의 다른 글
[Lua] 상속 구조 만들기 (0) | 2021.07.27 |
---|---|
[Lua] 메타 테이블(Metatable) (0) | 2021.07.21 |