语法 – 是否可以在Lua中复制Ruby的method_missing?

前端之家收集整理的这篇文章主要介绍了语法 – 是否可以在Lua中复制Ruby的method_missing?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我很确定在Lua中,您可以使用给定的Metatable的__index,__ newindex和__call来粗略地复制 Ruby的method_missing.我有点:
  1. function method_missing(selfs,func)
  2.  
  3. local Meta = getMetatable(selfs)
  4. local f
  5. if Meta then
  6. f = Meta.__index
  7. else
  8. Meta = {}
  9. f = rawget
  10. end
  11. Meta.__index = function(self,name)
  12. local v = f(self,name)
  13. if v then
  14. return v
  15. end
  16.  
  17. local Metahack = {
  18. __call = function(self,...)
  19. return func(selfs,name,...)
  20. end
  21. }
  22. return setMetatable({},Metahack)
  23. end
  24.  
  25. setMetatable(selfs,Meta)
  26. end
  27.  
  28. _G:method_missing(function(self,...)
  29. if name=="test_print" then
  30. print("Oh my lord,it's method missing!",...)
  31. end
  32. end)
  33.  
  34. test_print("I like me some method_missing abuse!")
  35.  
  36. print(this_should_be_nil)

我的问题是:虽然语法类似,我当然可以使用它来复制功能,但它引入了一个突破性的错误.你在应用method_missing的表的上下文中使用的每个变量永远都不是nil,因为我必须返回一个可以被调用的对象,以便将潜在调用的降压从索引函数传递给实际的调用.

ie在定义了如上所述的全局method_missing之后,尝试调用未定义的方法’test_print’按预期运行,但是当索引时test_print的值是非零的,并且未响应的其他方法/变量,如this_should_be_nil是非零.

那么有可能避免这个陷阱吗?或者,如果不修改语言源本身,语法是否可以支持这种修改?我想象在Ruby中,索引和调用是如何类似的,而在Lua中它们是截然不同的.

解决方法

您可以通过使nil值可调用来避免此问题.
不幸的是,这只能从主机代码(即C程序)完成,而不能从Lua脚本完成.

Pascal代码

  1. function set_Metatable_for_any_value_function(L: Plua_State): Integer; cdecl;
  2. begin // set_Metatable_for_any_value(any_value,mt)
  3. lua_setMetatable(L,-2);
  4. Result := 0;
  5. end;
  6.  
  7. procedure Test_Proc;
  8. var
  9. L: Plua_State;
  10. const
  11. Script =
  12. 'set_Metatable_for_any_value(nil,' +
  13. ' { ' +
  14. ' __call = function() ' +
  15. ' print "This method is under construction" ' +
  16. ' end ' +
  17. ' } ' +
  18. ') ' +
  19. 'print(nonexisting_method == nil) ' +
  20. 'nonexisting_method() ';
  21. begin
  22. L := luaL_newstate;
  23. luaL_openlibs(L);
  24. lua_pushcfunction(L,lua_CFunction(@set_Metatable_for_any_value_function));
  25. lua_setglobal(L,'set_Metatable_for_any_value');
  26. luaL_dostring(L,Script);
  27. lua_close(L);
  28. end;

输出

  1. true
  2. This method is under construction

猜你在找的Lua相关文章