lua-users home
lua-l archive

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


One solution I've used to problems like this is to define a table of
tables.

Instead of having the table {key1=val1, key2=val2, ... } you can use
{keys={key1=1, key2=2,...},vals={val1, val2,...}}

Then instead of writing struct[key], you can say
struct.vals[struct.keys[key]]. That's a little hard to type all the time,
but it's easy enough to provide gettable/settable methods which do it.

With this system, you can distinguish between keys which are not present
(struct.keys[key] is nil) and keys which are present but are nil
(struct.vals[struct.keys[key]] is nil).

The other advantage to this methodology is that the original ordering of
keys is preserved, although it's not preserved in a particularly useful
fashion. I have at times resorted to putting a third element in the
structure which is the inverse of the first one; i.e. it maps indices to
keys. This allows iteration to proceed in the order of insertion, which can
be extremely useful.

See my page on ExtendingForAndNext for an experiment on building
non-standard iterations into Lua.

R.



                                                                                                  
                    "Jay Carlson"                                                                 
                    <nop@nop.com>               To:     Multiple recipients of list               
                    Sent by:                    <lua-l@tecgraf.puc-rio.br>                        
                    owner-lua-l@tecgraf.        cc:                                               
                    puc-rio.br                  Subject:     Re: XMLRPC 0.0 for Lua               
                                                                                                  
                                                                                                  
                    27/11/01 10.30                                                                
                    Please respond to                                                             
                    lua-l                                                                         
                                                                                                  
                                                                                                  




> I've put an initial release of client/server bindings for Lua for XML-RPC
at
> http://www.place.org/~nop/luaxmlrpc-0.0.tar.gz . It contains my lxp expat
> binding, and uses LuaSocket for client transport.

Argh, you knew there had to be a reason why it was version 0.0.  I just
found it.  There's a hole in the type system.

Let's say you want to transmit a struct, {early=false} which looks like
this
in XML-RPC on the wire:

<struct>
  <member>
    <name>early</name>
    <value><boolean>0</boolean></value>
  </member>
</struct>

XML-RPC false is mapped to Lua nil.  There's no way to send that struct,
because the Lua table is {early=nil}, which is equal to {}.  (Similarly,
arrays with a first element of false fail the "is this an array" test.)

OK, so what can be done to fix this up?  I want to support the echo test in
Lua as function echo(v) return v end, so at the least there has to be some
kind of strict mode, such that a round trip through the type system doesn't
alter semantics.

First option: in-band signalling.  Make an XMLRPC.false (which will have to
evaluate true in the Lua sense).  It's painless to support this outbound,
such that clients sending messages and servers returning values can use
this
if they have to transmit such structs and arrays.  It's more painful to
support it inbound, where all values from the network have to be carefully
treated---"if v and v~=XMLRPC.false".

Second option: out-of-band signalling.  Add an additional (non-string,
non-numeric) key to structs and arrays that indicates which elements exist
but have false (aka nil) values.  This makes iteration less fun.

Third option: magic tables.  As above, but hide the is-present key behind a
layer of tagged "settable".

I think I'll make XMLRPC.false always available for outbound values, and
leave inbound false mapped to nil unless a "strict" flag is set.  I'll
probably make the strict flag global at first, but later it can be a
per-function flag in the registry.

Of course, XMLRPC passed the validator test and successfully interacted
with
a bunch of network services even with this hole, so it's not like you can't
use it... :-)

Jay