Bitten by singletons

2009-09-06

This weekend I have been bitten by some singletons. They have annoyed me so much that I am writing this blog about them. I will expose the singleton as a dangerous construct. Tempting, but dangerous.

Singletons, or K_GLOBAL_STATIC as they are called in the KDE world can do a lot of harm because they are sneaky. The are a source of hidden information that makes your function calls behave in unexpected ways.

Singletons are global instances of classes. They contain data that is not obvious in a stack trace. Take for example this function:

other people have done so convincingly.

Instead, I’ll tell a tale about how two singletons that are making command-line scripting of KWord impossible for now. The two protagonists in this tale are KoPluginLoader and Kross::Manager.

KoPluginLoader is a singleton that keeps a registry of the plugins that are loaded in KOffice applications. If you want to put a shape in your KOffice application, you have to ask KoPluginLoader, because KoPluginLoader loads the the code that is the shapes.

So what about Kross::Manager? Kross::Manager can, like the name suggests, be dangerous. If you can avoid it, do not cross a cross manager, especially not when it is in charge of your objects. And that is exactly what it is when your run kross from the command-line. Kross::Manager is a singleton that keeps track of all your script variables. If you run a script in kross, the variables you use are deleted when the K_GLOBAL_STATIC Kross::Manager is deleted, which is after the main() function ends.

And this is where the problem occurs. Here is a simple kross script that demonstrates it: