lua-users home
lua-l archive

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


Hi,

Zeljko Covic wrote:
> 
> I'm trying to run script described in table like this:
> 
> p1=1
> p2=2
> 
> function action1(p)
> :
> end
> 
> script={
> {action= action1, arglist={p1}},
> {action= action2, arglist={p2}},
> .
> }
> 
> using code like this:
> 
> for ....
>     call(script[i].action,  script[i].arglist)
> end
> 
> Now,  I'd like to change values of arguments (p1, p2...)  at run time,
> from within an action. Unfortunately,  this has no effect on arguments
> passed to actions since script table is already built with initial
> values of arguments.
> 
> Is there any workaround for such thing?  Do I need something like
> pointers or what?

Tables are the pointers of lua!  They are passed by reference so you
may change the contents of them and that's globally visible.
The call function explodes your arglist-table and passes each element
as a seperate argument to action.  That's why you can't change it.

A couple of solutions:

a) It seems you're not interested in the error protection possible with
   the call statement.  So the simple solution is to call the action
   directly with the arglist table as it's single argument:

      script[i].action(script[i].arglist)

   (A call(script[i].action, { script[i].arglist }) would do the same
   but more slowly.)

   Now your action gets only a single argument - an array of parameters.
   Your actions should be defined like this:

      function action1(arg)		-- arg is exactly what's in arglist
         print(getn(arg), arg[1])	-- access arguments
         arg[1]="hello"			-- change them
      end

   If arglist is a simple object (ie string) that string is passed
   and you can't change it.  To change future arguments, you have to
   pass a table.
   
b) Your action may opt to return the new parameters:

      local newargs = call(script[i].action, script[i].arglist, "px")
      if newargs then
         script[i].arglist = newargs
      end

   Now your functions have to return the future parameters:

      function action1(a,b,c)
         ...
         return a,b+1,c		-- keep a and c, increment b
      end     

c) You may slightly redesign your script table and pass the elements
   directly:

   The script definition:

      script={
         { action=action1, foo=p0; p1, p2, p3 },	-- note the ;
         ...
      }

   The call:

      script[i].action(script[i])

   or using an alternative syntax:

      script[i]:action()

   And how the actions have to be build:

      function action1(arg)
         arg[1] = arg[1] + arg[2]	-- access and change args
         arg.action = action1b		-- may even change the action itself
         print(arg.foo)			-- or use named args
         arg.bar = "hello"		-- or add new elements
         ...
      end


See?  The tables are just what pointers to structures are in C.  Just
more flexible and simpler to use *g*

Ciao, ET.