Method-chaining and Simple-types as objects

Daniel B. Faken faken at cascv.brown.edu
Wed May 18 11:25:36 PDT 2005


Hello all,

  For what its worth, here is a DBus interface design to support sending 
messages to Integers, Floats, etc. and to combine method calls that would 
normally be sent individually.
  I'm interested in getting feedback on this; esp.: is there a better way?  
does anyone care?  can we make some kind of pseudo-standard?

Generic method: 'methodCallChain( (no-args-methodname | [methodname, 
arg*])* )':
  - takes a list, where each element is an array, containing:
   + an optional integer indicating which of multiple return values is to 
     be used for the next method call  (default is 1).
   + the method-name (a string)
   + any input parameters for the method
  The first method is applied to the receiving object.
  If the method in question takes no args, and you only want the first arg 
to be passed along the chain, you can just give the (string) name of the 
method instead of the array.

In combination, these allow:
* Using *native* types in the remote process.
* sending messages to simple-types (integers etc.), when they are the 
return-value of  a method-call.  (but see below for a more general scheme)
* combining what would be multiple inter-process calls into a single one.

An example:
  Say my remote process (e.g. python) supports Bignums 
(arbitrary-precision integers), and that /pgpinfo contains some PGP-key 
information.
  Now if /pgpinfo->key() returns a bignum so big that it doesn't fit in an 
unsigned-64, then it will probably be encoded as a DBus object specific to 
the python process.
  But if it returns a bignum that *does* fit in a simple-type (e.g. 
uint64), then the python<->dbus interface is likely to convert it to a 
simple type.
  Now what if I want to send a message to the key?  In the former case, 
the message will go to python, but in the latter to my local 
implementation.
  e.g. /pgpinfo->key()->factorModulo(23940) may or may not fail depending 
on the size of the key.

With the above-mentioned chaining, though, I can do
  /pgpinfo->methodCallChain('key', ['factor', 23940])
which will return the correct result.
  This will also save a round-trip and possibly bignum-conversions.

With a little trickery in python we can turn this into a prettier:
  /pgpinfo.callChain(2).key().factor(23940)
where the (local) method callChain(2) wraps /pgpinfo into an object for 
which method calls will not be stored up until there are <2> of them, and 
then will be passed as a 'methodCallChain' method-call.


Two related ideas:

What if I want an object that represents a native-simple-type in another 
process?  With the above, I could do something like
  x = /Integer.callChain(2).new(3392349)
  x.factor()
but then 'x' isn't really a remote value - it is a python-wrapped object 
waiting for another method-call before it evaluates.
A more direct way might be to have a special object on 
the other process to handle conversion to a named-object.  For example,
  x = /PythonProc.makeObject(3392349)
  x.factor()

The 'object path' could be automatically generated to be unique.

Another way to go about this would be to have a Generic (global) method 
'asObject', which would return an object no matter what its type was.  
Combined with chaining, one could then do:
  x = /Integer.callChain(2).new(3239393).asObject()
and 'x' would be a real DBus object, say with a path 
/PythonProc/Integer/0x2394934

This brings up my other thought, which is the object-paths of 
simple-types.  For some types the value can be directly embedded in the 
path.  E.g. the integer '-4' could have path '/Integer/negative/4', or the 
float 0.131415 could be '/Float/0/131415'.
  This would also be convenient for debugging, and could allow local 
decoding of values when you know you want local values.



-- Implementation --
I have actually implemented the naming mechanism above, and 
'methodCallChain' and 'asObject' methods should be quite easy to 
implement.
  As far as my actual platform, I've been implementing Smalltalk bindings 
in Squeak (squeak.org) in order to talk with other scripting languages 
(python, lua, tcl).

  I see much traffic on the DBus list regarding C bindings like GLib.  
The content of this posting may not seem as relevant if you are calling 
*out* to C.  But, if you are trying to interface languages where 
"Everything is an Object" (e.g. Smalltalk), I think some solution of this 
nature will be important.

cheers,
Daniel




More information about the dbus mailing list