GjsでもJavaScript

GNOMEではSeed以外でもJavaScriptでプログラムが書けます。それがgjs(Gnome JavaScript)です。こちらの方が名前が勝ってますが、残念ながらGNOMEとして採用されませんでした。
サンプルコードは、

$ rpm -ql gjs | grep /usr/share/gjs-1.0/
/usr/share/gjs-1.0/dbus.js
/usr/share/gjs-1.0/gettext.js
/usr/share/gjs-1.0/jsUnit.js
/usr/share/gjs-1.0/lang.js
/usr/share/gjs-1.0/signals.js
/usr/share/gjs-1.0/tweener
/usr/share/gjs-1.0/tweener/equations.js
/usr/share/gjs-1.0/tweener/tweenList.js
/usr/share/gjs-1.0/tweener/tweener.js

等があります。しかし、Gtkは無いので、、、
http://git.gnome.org/browse/gjs/tree/examples/gtk.js
こちらをどうぞ。

ということで、いつものHelloプログラムです。

#!/usr/bin/env gjs
const Gtk = imports.gi.Gtk;
Gtk.init(0, null);
let win = new Gtk.Window();
win.connect("destroy", Gtk.main_quit);
let button = new Gtk.Button({label:"Hello"});
button.connect("clicked", function(){win.destroy();});
win.add(button);
win.show_all();
Gtk.main();

ここでのポイントはいくつかあります。

const Gtk = imports.gi.Gtk;

Gtk = imports.gi.Gtk;の前にconstが付いてます。
これが無いと警告が出ます。

    JS ERROR: !!!   WARNING: 'assignment to undeclared variable Gtk'
    JS ERROR: !!!   WARNING: file './hello.js' line 2 exception 0 number 156

なので付けましょう。
http://git.gnome.org/browse/gjs/plain/doc/Style_Guide.txt
ここに一応書かれてます。説明はImports時のCamelCase推奨等ですが、importsがあるところでは必ずconstが使われてます。

次に、Gtk.init(0,null);ですが、gsjでの引数の受け取り方が分からない。。。なので、とりあえずサンプルにしたがいました。

そして、

let win = new Gtk.Window();

let は戻り値で初期化する場合は付けた方が良いそうです(varも使えますが、let が推奨です)。そして、windowだと以下のエラーになります。

    JS ERROR: !!!   Exception was: TypeError: redeclaration of const window
    JS ERROR: !!!     lineNumber = '4'
    JS ERROR: !!!     fileName = './hello.js'
    JS ERROR: !!!     stack = '@./hello.js:4
'
    JS ERROR: !!!     message = 'redeclaration of const window'
TypeError: redeclaration of const window

どこかでwindowがconstで定義されているらしいです。

次に、connectでは、buttonとwinで別々に割り当ててます。buttonの"clicked"にGtk.main_quitを割り当てるとSEGVになります。原因は深く探ってません。まぁ、きちんとwin.destroyを呼び出して、そこでGtk.main_quitを呼び出しましょう。

win.connect("destroy", Gtk.main_quit);
...
button.connect("clicked", function(){win.destroy();});

button.connectでfunction()を使って無名関数を使ってますが、ここでGtk.main_quit();を後に書いても大丈夫です。そうすることで、winがdestroyされた後にGtk.main_quitが呼び出されます。コンテキストに依存するコードは美しくないとは思いますが。

ということでGjsについても使えることがわかりました。しかし、gjsはドキュメントが少ないので、ちょっと厳しいですね。個人的にはSeedの方がおすすめです。