1

I'm new to Vala and trying to understand how the language works. I usually use script languages like Python or JavaScript.

So, my question is why are there three ways of class constructor definition and how does the GObject style constructor work?

For the best understanding lets make an analogy with python:

Python class definition

class Car(object):
  speed: int

  def __init__(self, speed): # default constructor
    self.speed = speed # property

And Vala

class Car : GLib.Object {
  public int speed { get; construct; }

  // default
  internal Car(int speed) {
    Object(speed: speed)
  }

  construct {} // another way
}

I was reading the Vala tutorial section about GObject style construction, but still do not understand how Object(speed: speed) works and for what construct is needed?

Jens Mühlenhoff
  • 14,565
  • 6
  • 56
  • 113
Ennjin
  • 47
  • 4
  • This is basically a duplicate of this question: https://stackoverflow.com/questions/33003942/vala-different-type-of-constructors/33006252 – nemequ Jan 23 '20 at 23:06
  • Does this answer your question? [Vala different type of constructors](https://stackoverflow.com/questions/33003942/vala-different-type-of-constructors) – nemequ Jan 23 '20 at 23:06
  • Sure, I had seen this answers. But I need to understand how does GObject work. For example [here](https://github.com/elementary/appcenter/blob/master/src/MainWindow.vala#L56). Is there another way to provide application object to parent class? – Ennjin Jan 24 '20 at 06:32

1 Answers1

1

Vala was developed as a replacement for the manual effort needed to write GLib based C code.

Since C has no classes in GLib based C code object construction is done in a different way than in say C# or Java.

Here is a fragment of the output of valac -C car.vala for your example code:

Car*
car_construct (GType object_type,
               gint speed)
{
    Car * self = NULL;
    self = (Car*) g_object_new (object_type, "speed", speed, NULL);
    return self;
}

So Vala emits a car_construct function that calls the g_object_new () method. This is the GLib method used to create any GLib based class, by passing its type and construct parameters by name and value arguments one after another, terminated by NULL.

When you don't use construct properties it won't be possible to pass parameters via g_object_new () and you'd have to call the setter, for example:

Car*
car_construct (GType object_type,
               gint speed)
{
    Car * self = NULL;
    self = (Car*) g_object_new (object_type, NULL);
    car_set_speed (self, speed);
    return self;
}

Here car_set_speed () is called instead of passing the value via g_object_new ().

Which one you prefer depends on a few factors. If you do interop with C code often and the C code uses construct parameters, you want to use GObject style construction. Otherwise you are probably fine with the C#/Java style constructors.

PS: The setter is also auto generated by valac and will not only set the property value, but notify any listeners through the g_object_notify () system.

Jens Mühlenhoff
  • 14,565
  • 6
  • 56
  • 113
  • Thank you for answer! How I can see, the gtk (and ecosystem around this one) library require the gobject style way, are right? For another cases I can use C#/java construct style – Ennjin Jan 23 '20 at 18:52
  • No, you can almost always use C#/Java style constructors. Only if you want to provide a library for other users to consume you can consider using GObject style although even there it is not strictly necessary. – Jens Mühlenhoff Jan 24 '20 at 00:19
  • In such a case, how I can extend [Gtk.ApplicationWIndow](https://valadoc.org/gtk+-3.0/Gtk.ApplicationWindow.ApplicationWindow.html) class without calling `Object(application: application)`? – Ennjin Jan 24 '20 at 06:21
  • That is a different question. This question is about how GObject style construction works. Please create a new StackOverflow question. – Jens Mühlenhoff Jan 24 '20 at 11:29