Login
Newsletter
Werbung

Do, 3. Februar 2011, 15:00

Programmieren mit Vala

Beispiele

Dies soll keine Einführung in Vala sein, aber der geneigte Leser wird eine Vorstellung davon bekommen, wie sich Vala anfühlt und welche Features er erwarten kann.

Den Anfang macht ein kleines Hello-World-Programm:

public class BeispielApp : GLib.Object {
    public void schreibe_nachricht() {
        print("Hello World!\n");
    }

    public static int main(string[] args) {
        var bsp = new BeispielApp();
        bsp.schreibe_nachricht();
        return 0;
    }
}

Der Einsprungspunkt eines jeden Vala-Programms ist wie in C die main-Funktion. Als Parameter wird ihr ein Array von Strings übergeben, in dem sich die Argumente befinden, mit denen das Programm aufgerufen wurde.

Die main-Funktion leitet ein Objekt bsp von der Klasse BeispielApp ab, ruft dessen Methode schreibe_nachricht() auf und terminiert mit dem Rückgabewert 0, wodurch das Programm zu Ende gelaufen ist. Die Methode bsp.schreibe_nachricht() bedient sich der Funktion print(), um »Hallo Welt«, gefolgt von einem Zeilenumbruch, in die Standardausgabe zu schreiben.

Hinter dem Klassenbezeichner BeispielApp ist, getrennt von einem Doppelpunkt, die Basisklasse angegeben, deren Eigenschaften die neu definierte Klasse BeispielApp erben wird. Sie heißt Object und stammt aus dem Namensraum GLib. Es handelt sich um nichts Geringeres als die berühmte GObject-Klasse selbst. Sie ermöglicht, in der Klasse BeispielApp Features wie Properties und Signals zu verwenden.

Ohne jetzt irgendeinen Grund dafür vorschieben zu wollen: Es soll eine Property in das Beispielprogramm eingebaut werden. Properties sind dem C#-Programmierer gewiss bekannt. Sie erlauben es, für ein Element eines beliebigen Typs Funktionen zu bestimmen, die den Abruf (»Getter«) und das Setzen (»Setter«) des Wertes übernehmen. Die überarbeitete Klasse BeispielApp besitzt eine Property namens nachricht. Beim Setzen von nachricht wird nicht der alte Wert überschrieben, sondern der dem Setter übergebene Wert zum alten addiert. Eine Addition von zwei Strings ist dabei nur eine Aneinanderreihung der beiden Summandenstrings.

public class BeispielApp : GLib.Object {
    private string _nachricht = "";
    public string nachricht {
        public get {
            return _nachricht;
        }
        public set {
            _nachricht += value;
        }
    }

    public void schreibe_nachricht() {
        print("%s\n", nachricht);
    }

    public static int main(string[] args) {
        var bsp = new BeispielApp();
        bsp.nachricht = "Hello";
        bsp.nachricht = " ";
        bsp.nachricht = "World!";
        bsp.schreibe_nachricht();
        return 0;
    }
}

Darüber, dass eine Property verändert wurde, kann man sich bequem informieren lassen, indem man eine Funktion mit dem notify-Signal verbindet. Dazu braucht der Programmierer nicht einmal eine eigene Methode zu schreiben. Er kann auf Funktionen, die mitten im Code einer anderen Funktion definiert werden, zurückgreifen. Diese so genannten Lambdafunktionen haben Zugriff auf Variablen der sie umgebenden Funktion.

...
    public static int main(string[] args) {
        var bsp = new BeispielApp();

        bsp.notify["nachricht"].connect( () => {
            print("Wert von nachricht: %s\n", bsp.nachricht);
        });

        bsp.nachricht = "Hello";
        bsp.nachricht = " ";
        bsp.nachricht = "World!";
        bsp.schreibe_nachricht();
        return 0;
    }
...

In einem nächsten Schritt soll das Programm die Argumente in die Standardausgabe schreiben, mit denen es aufgerufen wurde. Das Programm wird also zum Beispiel so verwendet werden:

$ ./HW hallo welt? das ist banal!

Dazu iteriert man mit der Kontrollstruktur foreach über das Array args, das main beim Aufruf übergeben wird. Feld Nummer 0 des Arrays enthält (wie z.B. auch in C) den Dateinamen des Programms. Man braucht also mindestens ein zwei Felder langes Array, um überhaupt eine Nachricht zum Ausgeben zu haben. Wie lang das Array ist, lässt sich ganz einfach durch das Element length des Arrays feststellen.

Die Strings, die dem Programm übergeben wurden, müssen nun der Reihe nach zum Feld nachricht hinzugefügt werden. Dazu bedient man sich eines Features von Vala, das Slicing genannt wird. Der Ausdruck ist bildlich und heißt soviel wie »man schneidet sich eine Scheibe ab« von diesem Array.

...
    public static int main(string[] args) {
        if(args.length < 2) {
            print("Syntax: HW <nachricht1> <nachricht2> ... <nachricht n>\n");
            return -1;
        }

        var bsp = new BeispielApp();

        bsp.notify["nachricht"].connect( () => {
            print("Wert von nachricht: %s\n", bsp.nachricht);
        } );

        foreach(string s in args[1:args.length]) {
            bsp.nachricht = s + " ";
        }

        bsp.schreibe_nachricht();

        return 0;
  }
...

Der Teil des Arrays, der die übergebenen Nachrichten-Strings enthält, beginnt mit Feld 1 und endet mit dem letzten Feld. Da die Nummer des letzten Feldes der Anzahl an Feldern im Array entspricht, sieht das Slicing-Statement folgendermaßen aus:

args[1:args.length]

Das Ergebnis dieses Statements ist ein neues Array. Dies liegt nicht physisch im Speicher vor, sondern existiert nur logisch in Vala. Über dieses neue Array wird dann mit einer foreach-Schleife iteriert.

Um die Nachricht anstatt auf die Konsole in ein Fenster zu schreiben, muss die Funktion schreibe_nachricht() umgestaltet werden und kurz vor Ende von main die GTK-Hauptschleife gestartet werden.

Die Initialisierung von GTK+ muss geschehen, bevor schreibe_nachricht() gerufen wird:

...
    void schreibe_nachricht() {
        var window = new Gtk.Window (Gtk.WindowType.TOPLEVEL);
        window.set_default_size (400, 50);
        window.destroy.connect (Gtk.main_quit);
        window.add(new Gtk.Label(nachricht));
        window.show_all();
    }
...
    Gtk.init(ref args); bsp.schreibe_nachricht();
    Gtk.main();

    return 0;
    }
...

Beim Kompilieren ist jetzt das Compilerflag --pkg gtk+-2.0 erforderlich:

$ valac --pkg gtk+-2.0 HelloWorld.vala

Ein ausführliches Tutorial sowie viele weitere Beispiele – unter anderem zum Programmieren mit DBus, einigen Netzwerkbibliotheken und der Medienwiedergabe mit GStreamer – gibt es auf der Vala-Webseite.

Kommentare (Insgesamt: 102 || Alle anzeigen )
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung