Exploring Desktop Objects #1

August 16, 2012

Recently I played a little bit with Pharo (which is a fork of Squeak Smalltalk) and I was quite impressed with it. Since this was my first connection with Smalltalk, the language simplicity and clarity struck me hard, wondering why we are still living in dark ages of C++/Java or whatever language that is daring to call itself Object Oriented.

A perfect companion for this language comes in form of it's own environment: you have a full desktop under single executable which isn't desktop in a normal sense: it is much more like environment of objects, where everything you touch and move (window, button) is a true object.

Of course, every sane GUI C++ program will use object notation for buttons or windows, but at the end, they are compiled down to assembly and you are done with it. To have a false sense of ability to change it, you would modify some configuration files, reread them and load the program again.

With Smalltalk is different: if you want to change how button looks in certain window, you just get it's object and call whatever method you can call (in Smalltalk parlance: you send a message). Or, if you, at some point would like to see how this window is written, you simply query it's source code.

If you are still not convinced, check thesevideos from Alan Kay's Etech Presentation. Remember that was 2003 and we still can't do many of those things with (insert your favorite language here), no matter how fancy it is.

But, this article is not about how Smalltalk is glorious but what can be done to improve current situation. And some things can be done indeed, even if we are still living in stone age of modern languages(sic).

Now lets go to the matter.

Today modern way to communicate between desktop components and applications is DBusso situation here is very much status quo. DBus became stable, everyone use it and everyone is happy.

DBus brings notation of object paths, interfaces and methods; you can see object paths as instances living in certain namespace, which is pretty neat since you will have a lot objects floating around.

So DBus is very much object oriented, but why we are still have stone age tools to handle it? I'm not counting here language bindings (where btw. some of them are awesome), but the tools for exploring current objects (or object paths) and their context. Let we see what we have:

  • standard tools shipped with dbus ( dbus-monitor and dbus-send): well unless you know how to manually encode the message with array of strings or, for God sake, struct of arrays and dictionaries, you have to look somewhere else
  • qdbusviewer and qdbus: much better, comes with Qt. Even qdbusviewer will popup a dialog to fill method arguments when you are going to call that method. However, services which do not have introspection data will make it unresponsive (you will need to restart it). Setting complex parameters (like arrays or dictionaries) is not possible.
  • DBus Explorer: never tried it, but C#/Mono background decided for me to never try it; I don't have mono installed and not planning to do so.

How about some tool with exploring ability and ability to write and call custom code from the same place? Or maybe to have some IDE capabilities like generating code or displaying documentation of selected methods? Unless you are going to write it, there isn't one.

Why this matters when we have nice language bindings and even better archaic tools like dbus-send?

Well, let suppose you are going to write a client for PackageKit, but your language doesn't have ability to integrate packagekit-glib2 (or it was packagekit-glib:P) or simply, you don't want to add another library as dependency?

In that case, the only solution is to read reference api where you will get lost in a matter of seconds. Who needs examples when all methods are nicely documented and colored. What to call in which order? Well, either read the code or use dbus-monitor.

With the same approach applied above, if you are going to write your console http client (for example), you would either have to consult firefox source code or use wireshark to decipher http protocol. C'mon people, we are not living in '90-ties any more; we are lazy today and we prefer to see examples first.

Or, let put PackageKit aside (as we don't write package management tools every day). How about to see what (DBus) services we have on our system, which interfaces and objects they exposes? Or simply, your program exposes services; how the hell you are going to test it? Again, you will use either dbus-send or write some testing code with python/ruby/etc. (before that make sure to download all their dependencies as their developers like to depend on as much libraries as possible).

So to make situation in this field less painful as possible, the last couple of days I was working on edelib-dbus-explorer (it comes with edelib from svn). With it, I was trying to address above issues that itched me for some time.

edelib-dbus-explorer (as you can see from the shot) looks much like qdbusviewer, in layout form, but adds scheme interpreter as the main communication point (or better say edelib-script, which is nicely packaged tinyscheme with a bunch of addons).

In a Smalltalk fashion, you explore services and objects, find some method and hit 'Send to editor': you will get a code snippet ready for evaluation. Then, you continue to write some more code, add another method call and at the end, save everything. Could it be more complicated?

edelib-dbus-explorer recognizes almost all DBus types (except signatures and file descriptors); return values will be converted to scheme objects (simple types to corresponding scheme values, like DBUS_STRING to string and complex to lists, or list of lists like dictionaries). For input types (those that serves as arguments to method calls), explicit type designation must be appended as DBus is picky if you use uint32 or int16 because signature is different.

But, explicit typing is not an issue: when is instructed to generate code, all types will be correctly placed with added REPLACE_MEplaceholder, which must be replaced with appropriate values. Hitting Shift-TAB will jump between those placeholders.

Is this better than previous solutions? I'm confident it is and can be even better, which adds more room for improvements.

to be continued...