2012-08-03 4 views
0

나는 아무도 대답을 알 수 있는지 궁금 해서요 지금 까지이 문제를 찾고 있었는데 - 당신이 루아에서 nil 값을 색인하면 스크립트가 오류를 일으킨다 - 'variableName에 대한 attemp '- 무의미한 가치 - metamethod와 함께 그것을 대신 포착하고, 어떤 처리를하고, 오류를 내지 않을 수 있습니까? 예를 들어 변수 'num'이 정의되어 있지 않고 'num = 2'라고 말하면 __newindex 메타 메소드를 설정하여 일부 처리를 수행 할 수 있으며 변수 이름 - 'num'과 값 - '2' 하지만 'num [2] = 3'과 'num'이 정의되지 않았다면 오류가 발생합니다. 대신 __newindex처럼 그 이벤트를 캡처하여 nil 변수의 이름에 액세스하려고합니다. 'num'은 index - 2, set value - 3. 어떤 도움을 주시면 감사하겠습니다.루아 색인 null 값을

+0

질문이 완전히 명확하지 않습니다. num이 테이블 변수라고 말하는거야? 아니면 num은 스크립트에 대한 지역 변수일까요? –

+0

그것은 'num'이 아직 정의되지 않았지만 어쨌든 색인을 생성하려고합니다. 정의되지 않은 변수 이름을 원합니다. 'num', 색인 및 값을 사용하여 일부 작업을 수행 할 수 있습니다. 처리, __newindex를 사용하는 것처럼 – user1452276

답변

0

전역 테이블에서 __newindex 메타 메서드를 재정의 할 수 있습니다.

function OnNewIndex(tbl, key, value) 
    if tbl[key] == nil then 
     print(tostring(key).. " doesn't exist.") 
    end 
end 

setmetatable(_G, { __newindex = OnNewIndex }) 

num = 15 

그러나 기본적으로 나는 루아가이 동작을한다고 생각하지 않습니다.

num = 15 

변수 'num'을 전역 변수로 선언하고 값 15를 할당해야합니다. 이것을 엄격하게 검사하는 프레임 워크의 일부로 lua를 사용하고 있습니까?

편집 :이 같은 PCALL에 할당을 포장하는 것입니다 표면에 그것을 거품을 말도없이 이러한 오류 '캐치'하는 쉬운 방법 ...

pcall(function() num[2] = 15 end) 

이를 인쇄하면

, 당신 ' LL 출력을 얻을 :

적어도 당신에게 무슨 일이 있었는지 어떤 표시를 제공
false test2.lua:18: attempt to index global 'num' (a nil value) 

,이 기능을 명명하는 경우, 당신이 잠재적으로 복구를 시도 할 수있는 것 같아요. 당신은 아마 그냥 앞의 코드를 해결할 수있을 때

function TrySetValue() 
    num[2] = 15 
end 

local result, msg = pcall(TrySetValue) 
if (not result) then 
    num = {} 
end 

result, msg = pcall(TrySetValue) 
print(result, msg) 
print(num[2]) 

작업의 엄청 많이처럼 보인다.

+0

내가 충분히 명확하지 않은 것 같아요 : __newindex metamethod 문을 무시하는 경우 : num = 15, 여기서 num은 선언되지 않은 변수가 잡히고 문자열 'num'과 그러나 num : 2와 같은 문은 num이 선언되지 않은 곳에서는 __newindex를 덮어 썼는지 여부에 관계없이 오류가 발생합니다. 오류는 다음과 같습니다. 'num'- nil 값 '인덱스 시도' – user1452276

+0

예, pcall에서 과제를 래핑하지 않고 잡으려고하는 것을 '잡을 수있는 방법'이 실제로 있다고 생각하지 않습니다.) 오류를 복구하려고합니다. 당신이하고있는 일에 대해 생각해보십시오. _G 테이블에 대한 __index를 catch하고, 새 테이블을 만들고, __index를 catch하고, THAT에 값을 할당하려고합니다. 당신이 그것을 어떻게 할 것인지 정말로 모르겠다. 실제로 색인을 생성하기 전에 num을 먼저 명시 적으로 작성해야 할 때가있다. 그건 꽤 표준적인 프로그래밍 원리입니다. –

1

먼저 해결하려는 문제를 진술하면 더 쉽게 도움을받을 수 있습니다. 초기화되지 않은 전역이 사용되는 것을 방지하려고합니까? 당신은 메타 테이블로 그렇게 할 수 있습니다. 스크립트 오류가 앱에 결코 침투하지 않도록 노력하고 있습니까? pcall을 사용하면됩니다. 당신은 정말로 nil 글로벌의이 특정 사용을 잡으려고하고 있으며 어떤 방식으로 그것을 복구하려고합니까? 컨텍스트가 많을수록 다른 사람들이 생각지도 못했던 솔루션을 쉽게 찾을 수 있습니다. 당신이 numnil이고, 당신이 정말로 직접 그것을 감지 할 수 num[index] 잡으려면 당신이 설명한 상황에 관해서는

. num의 현재 값이 현재 환경 테이블 (일명 _ENV 또는 _G)에서 읽어

  1. 당신이 인덱스에 그 값을 시도 :

    이 두 부분이 있습니다. 당신이 그것을 메타 테이블을 줄 수 있도록 nil 테이블이 아니기 때문에

, 당신은 # 2를 감지 할 수있는 방법은 없습니다.

그러나 수는입니다.요구 사항에 따라하는 것은 당신 사용 # 1 다음 2를 감지 할 수 프록시 개체를 반환 할 수있다, 그러나이 전역 적 nil 수 없습니다 의미 할 것이다, 그래서이 같은 논리는 작동하지 않습니다

--- initialize globalFoo if it doesn't exists 
if not globalFoo then 
    globalFoo = CreateGlobalFoo() 
    .... 

물론 당신은 항상 이름 프록시 객체 NIL 같은 것을 할 수있는, 그래서 당신은 쓸 수 :

local nil_proxy_mt = { 
    __index = function(t,k) print('Attempted to index nil!') end, 
    __newindex = function(t,k,v) print('Attempted to index nil!') end, 
} 

local NIL = setmetatable({}, nil_proxy_mt) 

setmetatable (_G, { __index = function(t,k) return NIL end }) 
: 그런 식으로 작동하는 프록시 개체의

if globalFoo == NIL then -- globalFoo is not initilalize 
    globalFoo = CreateGlobalFoo() 

foo = num[2] 
num[2] = 15 
당신은! "인덱스 무기 호에 시도"거야

:이 중 하나를 시도하면 장소에두고

, 프로그램이 계속 실행됩니다.

+0

나는 월요일에 돌아와서 추가 의견을 게시 할 때 이것을 알려줄 것입니다. – user1452276