2015-01-18 5 views
2

다른 위치에있는 다른 함수 집합에 "게이트웨이"역할을하려는 빈 테이블이 있습니다.Lua metatable, 정의되지 않은 함수를 전달하는 방법은 무엇입니까?

tbl = {} 

나는 문자열로 다른 곳이 테이블에서 호출되는 함수를 전달하려는 :

tbl.someMethod("hello") 

내가 제한된 성공이 시도했습니다.

hand = { 
    __index = function(tbl, name) 
     hand[name] = function(...) 
      passToSomewhere(name, ...) 
     end 
    end, 
    __call = function(tbl, name, ...) 
     hand[name](...) 
    end 
} 
setmetatable(tbl, hand) 
tbl.someFunction("hello!", someTbl, someNumber) 

정의되지 않은 함수를 오류없이 던져 넣을 수있는 방법은 무엇입니까?

편집 : 더 자세히 내가 정의하고 하나의 호출에 테이블의 함수를 호출하기 위해 노력하고있어

:

tbl = {} 

hand = { 
    __index = function(tbl, name) 
    print(name) 
    tbl[name] = function(...) 
     print(...) 
    end 
    end 
} 
setmetatable(tbl, hand) 

s,e = pcall(tbl.help,"banana","goat") 
print(s) 

s,e = pcall(tbl.help,"banana","goat") 
print(s) 

이 코드가하는 일하지만 첫 번째 PCALL이 때문에 오류가 발생합니다 함수가 아직 정의되지 않았습니다.

내가 업데이트를 꽤 많이 알고 있고 내 스크립트가 호환되도록 유지하고이 라이브러리가 내 컴퓨터에 없을 수도있는 라이브러리를 사용하고 싶다고 말합니다. 일부 인터페이스에서이 라이브러리에 대한 호출을 전달하고 싶지만 여전히 같은 방식으로 함수를 호출 할 수 있기를 원합니다.

--For example I would like to call this function like this: 
someLib.doSomething(name, age, telephone) 

--Instead of passing it through another function: 
someOtherLib.invoke("someLib.doSomething", name, age, telephone) 

이것이 가능합니까?

편집 2 :

감사합니다. @greatwolf!

이것은 제 테스트 코드입니다. 에 업데이트 된 정보를 기반으로 좋아

tbl = {} 

hand = { 
    __index = function(tbl, name) 
    tbl[name] = function(...) 
     return print(name, ...) 
    end 
    return rawget(tbl, name) 
    end 
} 
setmetatable(tbl, hand) 

tbl.help("banana","goat") 
+1

어쩌면 당신은'손 [이름]'을 돌려 줄 필요가 있을까요? 그게 네가 무엇인지 확신 할 수 없지만'__index'가 아무 것도 반환하지 않으면'nil'을 호출하려고하는데 결국 에러가 발생합니다. – greatwolf

+0

더 간단한'setmetatable (tbl, {__ index = othertbl})'가 작동하지 않습니까? – lhf

+0

@greatwolf가 작동하도록하려면이 함수를 두 번 호출해야합니다. 그렇지 않으면 정의되지 않습니다. 나는 당신이 한 번에하려고하는 것을 할 수 없다고 생각합니다. – FortuneCookie101

답변

2

, 당신은 무대 뒤에서

someOtherLib.invoke("someLib.doSomething", name, age, telephone) 

에이 호출

someLib.doSomething(name, age, telephone) 

번역 루아합니다. , LHF의 제안이 너무

setmetatable(tbl, {__index = someOtherLib}) 

이제 작동됩니다 someOtherLib이 기능의 단지 테이블의 경우, 지금

__index = function(tbl, name) 
    tbl[name] = function(...) 
    return someOtherLib.invoke("someLib."..name, ...) 
    end 
    -- return tbl[name] works too, I used rawget to indicate 
    -- no further __index lookup should be done 
    return rawget(tbl, name) 
end 

: 무엇 당신은 당신이 방금 새로 만든 기능 등을 반환 할 필요가 거의있다 당신의 someOtherLib가 실제로 아직 그것을 호출하지 않고 호출 할 함수를 얻기 위해 어떻게든지 제공하는 경우, __index 여분의 폐쇄 래퍼

__index = function(tbl, name) 
    tbl[name] = someOtherLib.getFuncByName(name) 
    return tbl[name] 
end 
를 작성하지 않고이 릴레이 할 수

여기서는 __call 메타 메서드가 필요하지 않습니다.