Method-chaining and Simple-types as objects
Daniel B. Faken
faken at cascv.brown.edu
Wed May 18 11:25:36 PDT 2005
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,
- 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.
Say my remote process (e.g. python) supports Bignums
(arbitrary-precision integers), and that /pgpinfo contains some PGP-key
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
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
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:
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)
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)
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
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
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.
More information about the dbus