如何在 LUA 中重定向所有类调用?

好的,我在这方面有些困难,所以我会先给出一个简单的例子来说明:

假设我有一个“类”,让我们命名为 MyClass,假设它有一个名为 MyFunction 的函数,我们可以通过从任何 MyClass 对象调用该函数来访问它,比如 MyClassObject:MyFunction()

如果我没有访问那个函数的权限,并且想要添加一个在执行之前执行的新行为,我可以做类似于这样的事情:

MyClass.OriginalMyFunction = MyClass.MyFunction -- 存储旧函数

function MyClass:MyFunction(args)
    --执行之前做一些事情
    MyClass:OriginalMyFunction(args) --使用相同的参数调用原始函数
end

这只是一个简单的示例,但我需要做的是对类中的所有可能函数都做同样的处理。也就是说,在调用 MyClassObject 上的任何函数之前都要执行一些代码。

这是可能的吗?如果是,请告诉我该如何做?

原文链接 https://stackoverflow.com/questions/71294677

点赞
stackoverflow用户4070330
stackoverflow用户4070330

可以通过元表来实现,

以下是比较简单的例子:

local MyClass = {}
function MyClass:new()
  local newObj = {
    x = 0
  }
  self.__index = self
  return setmetatable(newObj, self)
end

function MyClass:get_x()
  print("hello from get_x")
  return self.x
end

local HookedMyClass = {}

function HookedMyClass:new()
  local t = MyClass:new()
  local mt = {
      __index = function(table, key)
          print("hook")
          return(MyClass[key])
      end
  }
  return setmetatable(t, mt)
end

local hooked = HookedMyClass:new()

print(hooked:get_x())
2022-02-28 13:14:12
stackoverflow用户7504558
stackoverflow用户7504558

下面是一个继承的例子,其中可以将一些代码添加到你的所有函数中:

function new (parent)
    local child =  {}
    for k,v in pairs(parent) do
       if type(v)=="function" then
          child[k] = function(...)
                      print("inherit:")
                      return v(...)
          end
       else child[k] = v
       end
    end
    return child
end

my_class = new(class)

class.bar("arg1","arg2")
my_class.bar("arg1","arg2")
print(class.a)
print(my_class.a)

结果:

bar arg1 arg2
inherit:
bar arg1 arg2
value
value
2022-02-28 14:01:47