2013-05-11 6 views
6

나는 문제가 예 이들 사이의 __index 메타 메소드의 행동에 차이가있는 이유를 이해하는 데 : lua: l.lua:8: attempt to call method 'speak' (a nil value)루아 메타 테이블 불일치

하다니 :

A = { __index = A } 
function A:speak() 
    print("I'm an A") 
end 
An_A = setmetatable({},A) 
An_A:speak() 

다음과 같은 오류가 발생됩니다

B = { __index = function(t,key) return B[key] end } 
function B:speak() 
    print("I'm an B") 
end 
An_B = setmetatable({},B) 
An_B:speak() 

예상대로 수행하여 I'm an B을 출력합니다. 이것이 내가 PIL의 this 섹션을 읽어 경우 이유를 이해하려고 노력에서


. 이것의

The use of the __index metamethod for inheritance is so common that Lua provides a shortcut. Despite the name, the __index metamethod does not need to be a function: It can be a table, instead. When it is a function, Lua calls it with the table and the absent key as its arguments. When it is a table, Lua redoes the access in that table.

나의 이해는 코드에서 (위의 인용문의 boldened segmenet에 따라) 테이블 A에서 수행 할 수있는 액세스의 원인, 'A'를 __index = A 포함하는 것입니다 : 그것은 상태. 이 경우 키 "speak"과 관련된 기능을 찾을 수없는 이유를 알 수 없습니다. 이 문제를 해결하기 위해 key과 연결된 값을 B 스 니펫에 입력하고 B에 함수 방법을 구현하기로 결정했습니다. 물론 __index = A 및 (B에서 적응) __index = function(t,key) return A[key] end은 동일한 효과를 나타냅니다.

모든 설명이 크게 감사하겠습니다.

답변

9

첫 번째 예에서 일어나는 일은 A.__index == nil입니다. 여기에 첫 번째 줄에 'A'를 만들 때 :

A = { __index = A } 

하여 할당이이 시점에서 아직 존재하지 않기 때문에 'A'는 nil 평가의 오른쪽. 그 결과, 나중에 여기에 메타 테이블을 설정하는 경우 :

An_A = setmetatable({},A) 

정말이 유사 뭔가 일을 끝 :

An_A = setmetatable({}, {__index = nil}) 

는 당신이하고자하는 일을 할 수 얻으려면을, 당신은에 있습니다 __indexnil이 아닌지 확인하십시오. 예를 들어, 테이블 건설 후에 할당하십시오 :

A = {} 
A.__index = A 

function A:speak() 
    print("I'm an A") 
end 
An_A = setmetatable({},A) 
An_A:speak()    --> outputs I'm an A 
+0

큰 설명을 해 주셔서 감사합니다. 이런 일이 발생하지 않았을 것입니다. 나는 다른 언어와 같을 것이라고 생각 했었습니다. 'f = λ n : f (n)'이 유효합니다. 건배 : – HennyH

+1

@HennyH :'f = function (n) return f (n) end'는 같은 이유로 루아에서 괜찮습니다. 상응하는 실패한 파이썬은'd = { "__index": d}'이지만 파이썬은'NameError'입니다. – Eric

+0

@Eric 어떤 재귀 함수도 같은 패턴을 따른다고 가정합니다. – HennyH