lua-users home
lua-l archive

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


Hi,

Let's suppose you are writing a library that produces a lot of table-based objects with operations, and you want the control the unnecessary production of new objects as result of manipulations. Think a complex number or matrix library, or things like that. For example:

  M = {}
  M.new = function ( s )
    return s or { n=0 }
  end

So, you want to provide methods that either produce a new object,  or store the result in a existing one. I've seen two style of APIs, one with separate methods:

  M.add = function ( a, b )
    return M.new{ n=a.n+b.n }
  end
  M.set_add = function ( a, b )
    a.n = a.n + b.n
    return a -- for concatenating calls
  end
  return M

  --usage:
  local m = require 'module'
       ...
  a = m.add( b,c )  -- produces object
  m.set_add( b, c ) -- store in place
  -- with adequate metamethods
  a = b:add( c ) -- produces object
  b:set_add( c ) -- store in place

And another alternative, with optional out parameter:

  m.add = function ( a, b, out )
    if out then
      out.n = a.n + b.n
      return out -- for concatenating calls
    else
      return m.new{ n=a.n+b.n }
    end
  end

  --usage
  local m = require 'module'
       ...
  a = m.add( b, c ) -- produces object
  m.add( b, c, b )  -- store in place
  -- with adequate metamethods
  a = b:add( c ) -- produces object
  b:add( c, b )  -- store in place
  b:add( c, d )  -- store in a different existing object


The option with the separate calls seems to lead to clearer user code, tough de API can get very long and annoying. The "out parameter" version allows to store the result in a separate object, thus is more flexible, while looking ugly sometimes. It also add a if-then check on every call. Any ideas or thoughts?


Jorge