Changing quickly between a final and derivable GObject class

When doing code refactorings, it is sometimes desirable to change between a final and derivable GObject class. So it is important that that operation can be done quickly, as every other small refactorings that you usually do in your code.

In fact, when refactoring some code, sometimes you want to quickly try something to see if the result is better. But if a certain refactoring task takes a lot of manual and boring steps, (1) it’s not a pleasure to do it and (2) if the result (after other refactorings) is not what you want, you’ve lost your time.

To evolve in the right direction, a code needs to be easily modifiable.

With the convention to put GObject instance variables in the Private struct for derivable types, and in the object struct for final types, changing between the two is currently quite burdensome (because there is no tools to do it quickly):

/* For a final type */
gint
my_object_get_foo (MyObject *object)
{
  return object->foo;
}

/* For a derivable type */
gint
my_object_get_foo (MyObject *object)
{
  MyObjectPrivate *priv = my_object_get_instance_private (object);

  return priv->foo;
}

Maybe in a library like GTK+, changing between a final and derivable type is not a common operation. But in an application, it can be more common. For example when you want to move a class from an application to a library (it can be an internal or external library), one way to do it is to move the re-usable code in the library and keep the app-specific code in a subclass. So in that case, the class in the library needs to be derivable!

There is, though, another convention that can be used with GObject: always use a Private struct, even for final types.

But, calling my_object_get_instance_private() in each function is quite cumbersome… With the old convention to have a 'priv' field in the object struct to access the Private struct, you don’t have that problem. For example:

/* Old convention: have a 'priv' field in the object struct. */
gint
my_object_get_foo (MyObject *object)
{
  return object->priv->foo;
}

Although for a library it’s better to not have the 'priv' field, I tend to prefer that latter code.

TL;DR: writing and refactoring GObject code in C can be quite painful, we need more tools. In the meantime, there can be a big difference just by following a different convention.

Edit: If you’ve read this blog post, you might think “just use Vala or Python or JavaScript! problem solved!”, but I still prefer the C language for GNOME development for reasons explained in this document. And to develop a library, the C language is the de facto language in GNOME.