lua-users home
lua-l archive

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


It was thus said that the Great Mike Jones once stated:
> 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. 

  To me, "event style framework" reads as "callbacks and promises" whereby
you pass around fragments of code to run as each event comes in.  For this
style, I use Lua coroutines to avoid the callbacks and to present code in a
straightforward way.  For example:

	function echo(socket)
	  socket:write(socket:read("*a"))
	  return echo(socket)
	end

My socket framework is event driven (backed by epoll()/poll()/select()
depending upon the Unix variant) but each connection is driven by a Lua
coroutine.  The socket:read() function will "block" until input is received,
then it resumes the coroutine.  the socket:write() will write as much out
until it would block, then (if it would and there's still output), it will
"block" until output can be written, with further output buffered.

  It makes writing networking code much nicer and it's easier to follow the
logic as it's imperative (and yes, I do use this at work where I'm
processing SIP messages).

  Now, on to your question.

> 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

  I dug through my archives and I found the following bit of code (cleaned
up---I was starting to learn Lua):

	function fappend(f1,f2)
	  return function(...)
	    return f2(f1(...))
	  end
	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.

  You could get fancy (or scary, depending upon your viewpoint):

	_function_mt =
	{
	  __concat = function(f1,f2)
	    return function(...)
	      return f2(f1(...))
	    end
	  end
	}

	debug.setmetatable(debug.getmetatable(print),_function_mt)

	dosomething = module1.dosomething .. module2.dosomething

	print = function(...)
	  log('debug',"calling print")
	  return ...
	end
	.. print ..
	function(...)
	  log('debug',"done calling print")
	  return ...
	end

  -spc (Betcha didn't know you could concat functions?)