我相当确定在 Lua 中,您可以使用给定元表的 __index
, __newindex
, 和 __call
大致复制Ruby的method_missing
.我有点:
function method_missing(selfs, func)
local meta = getmetatable(selfs)
local f
if meta then
f = meta.__index
else
meta = {}
f = rawget
end
meta.__index = function(self, name)
local v = f(self, name)
if v then
return v
end
local metahack = {
__call = function(self, ...)
return func(selfs, name, ...)
end
}
return setmetatable({}, metahack)
end
setmetatable(selfs, meta)
end
_G:method_missing(function(self, name, ...)
if name=="test_print" then
print("Oh my lord, it's method missing!", ...)
end
end)
test_print("I like me some method_missing abuse!")
print(this_should_be_nil)
我的问题是:虽然语法相似,我当然可以用它来复制功能,但它引入了一个破坏性错误。您在表上下文中使用的每个变量都应用了
method_missing
to 永远不会为零,因为我必须返回一个可以调用的对象才能pass the buck
从索引函数到实际调用的潜在调用。即在如上定义全局 method_missing 之后,尝试调用未定义的方法 'test_print' 会按预期运行,但索引时 test_print 的值为非 nil,以及其他未响应的方法/变量,例如
this_should_be_nil
非零。那么有没有可能避免这个陷阱呢?或者在不修改语言源本身的情况下,语法是否可以不弯曲来支持这种修改?我想困难在于如何在 Ruby 中索引和调用是类似的,而在 Lua 中它们是不同的。
最佳答案
您可以通过制作 nil
来避免这个问题。值可调用。
不幸的是,这只能从宿主代码(即 C 程序)中完成,而不能从 Lua 脚本中完成。
帕斯卡代码:
function set_metatable_for_any_value_function(L: Plua_State): Integer; cdecl;
begin // set_metatable_for_any_value(any_value, mt)
lua_setmetatable(L, -2);
Result := 0;
end;
procedure Test_Proc;
var
L: Plua_State;
const
Script =
'set_metatable_for_any_value(nil, ' +
' { ' +
' __call = function() ' +
' print "This method is under construction" ' +
' end ' +
' } ' +
') ' +
'print(nonexisting_method == nil) ' +
'nonexisting_method() ';
begin
L := luaL_newstate;
luaL_openlibs(L);
lua_pushcfunction(L, lua_CFunction(@set_metatable_for_any_value_function));
lua_setglobal(L, 'set_metatable_for_any_value');
luaL_dostring(L, Script);
lua_close(L);
end;
输出:
true
This method is under construction
关于syntax - 是否可以在 Lua 中复制 Ruby 的 method_missing?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19776211/