lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 3 October 2016 at 13:04, 云风 Cloud Wu <cloudwu@gmail.com> wrote:
>
>
> Mike Jones <mike@mikejones.in>于2016年10月3日周一 下午6:44写道:
>>
>> Hi,
>>
>> I am working on a project where I have basically an event style
>> framework, and I would like some way to "chain together" functions. I
>> have had a quick look at OO libraries for Lua but they don't seem to
>> be suited to what I am trying to do. I can't seem to find an example
>> that fits my use case of wanting parrallel modules providing the same
>> functions.
>>
>> Here is a short example of what I am doing at the moment:
>>
>> -- core function, defined in common header
>> function dosomething(arg)
>>     print("Orginal dosomething()")
>>    return 0
>> end
>>
>> -- module 1 included in script, adds extra code on to existing function
>> pre_module1_dosomething = dosomething
>> function dosomething(arg)
>>     print("Module 1 dosomething()")
>>     return pre_module1_dosomething(arg)
>> end
>>
>> In my example the functions are in different files, but that's the
>> basic pattern I am currently using to chain extra code on to the end
>> of a function that has already been defined. When executed it should
>> output "Module 1 dosomething()" followed by "Original dosomething()",
>> ie both functions get executed. Is there a better way of achieving
>> this sort of functionality? the use of the "pre_module1_dosomething"
>> variable to hold the parent function seems very ugly to me.
>>
>> - Mike Jones
>
>
> How about this one ?
>
> function dosomething(arg)
>   print("Orginal dosomething()")
>   return 0
> end
>
> local hook = {}
>
> function hook.dosomething()
> print("Module 1 dosomething()")
> end
>
> local function inject(original, hook)
> for method, func in pairs(hook) do
> local pre = original[method]
> original[method] = function (...)
> func(...)
> return pre(...)
> end
> end
> end
>
> inject(_ENV, hook)
>
> print(dosomething())

Perhaps I should explain how my files are laid out in case there's a better way.

header.lua - this file is always included/executed/whatever first, it
is actually embedded in to the executable at compile time... so this
would contain the original dosomething() function
module1.lua - this would contain some replacement dosomething()
module2.lua - this might contain another dosomething()
application.lua - this is the main lua application, and would start
with something along these lines:
require("module1")
require("module2")
...

my application would "run" application.lua (which should just set up
the environment), it would then call dosomething() from C code

using your example I think I would put this in header.lua:
function dosomething(arg)
  print("Orginal dosomething()")
  return 0
end

function inject(original, hook)
  for method, func in pairs(hook) do
  local pre = original[method]
    original[method] = function (...)
      func(...)
      return pre(...)
    end
  end
end

then in each module file I could do something like:

module1={}
function module1.dosomething()
    print("Module dosomething()")
end
inject(_ENV, module1)

It's a bit tidier than what I am doing at the moment, and it also
opens up the possibility of doing something else with variables using
the same syntax by changing the inject function.

I'll wait until tomorrow before refactoring my code just in case
someone else has a better suggestion, but this should do the trick.

Thanks,
Mike