Strange behavior of formatted string

Hello I am not sure I used the right place so forgive me if I a wrong.
To start with vala I updated the hello world code to display the number of click and close the app when 5 clicks happened.
When click is greater than 1 it should append “s” isn’t it?
But I got the following:
1 click
2 click (wrong right ? )
3 clicks
4 clicks

Why no s appended for 2 ?

int main (string[] argv) {
    // Create a new application
    var app = new Gtk.Application ("com.example.GtkApplication",
                                   GLib.ApplicationFlags.FLAGS_NONE);

    app.activate.connect (() => {
        // Create a new window
        var window = new Gtk.ApplicationWindow (app);
        var count = 0;

        // Create a new button
        var button = new Gtk.Button.with_label ("0 click");

        window.set_default_size(200, 200);

        // When the button is clicked, close the window
        button.clicked.connect (() => {  
            button.label = @"$(++count) click$(count > 1 ? "s" : "")";
            if (count == 5) {
                window.close ();
            }
        });

        window.set_child (button);
        window.present ();
    });

    return app.run (argv);
}

I have no clue about vala, but it is easy to guess: (++count) – when exactly is that statement executed? Similar problems happen to people with C and C++, so most newer languages avoid constructs like this.

According to the result it is executed.
It displays first
1 click
then
2 click. ==> count is indeed incremented and is equal to 2 so there should be an s.
Vala allows embedded variables and expressions in string templates. Clearly something goes wrong there, unless I am missing something.

If I pre-increment count out of the string formatting

++count;
 button.label = @"$(count) click$(count > 1 ? "s" : "")";

then it works as expected.

Which one is executed first? The test count > 1 or the increment ++count? You can’t just assume it’s executed from left to right if it’s the same expression. Pre-incrementing the count is indeed the correct answer: it will make the intent clear that you’re incrementing then updating the label.

That said, you should take a look at ngettext(). It does what you want to do while respecting the rules of the language so that when you enable translations for your app, you don’t end up with weird bugs (adding an s with a language that doesn’t use s as a plural mark, or worse a language that doesn’t have s in its alphabet at all :wink: )

Thanks it’s right, that is what I actually came to.
It seems there is no guarantee that the evaluation is executed from left to right in string prefixed with ´@’ .
Like I said this was just a hello world, first vala coding. There is no need to ++count in the string template.
Was happy to see quick reaction to my post.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.