Javascript and Gnome (2/)

Gjs

In my last post we saw how javascript became a first class citizen programming language in GNOME so, it’s time to see how well the language works in the platform, lets start.

According to the wiki:

Gjs is a Javascript binding for GNOME. It’s mainly based on Spidermonkey javascript engine and the GObject introspection framework.

Although this definition is quite accurate I prefer my own definition:

Gjs is javascript on steroids for the GNOME platform

And with “steroids” I mean some extra modules added to the interpreter and, obviously, GObject introspection.

So, lets dive a little deeper in GJS to see how those steroids plays in the language.

The venerable “Hello, world” example

Lets begin with the ubiquitous “Hello, world” example. Just open gedit, write the following line and save the file as hello.js

// Venerable Hello, world
//
// hello.js
print('Hello, world');

I assume you are confident typing commands in the terminal so, open gnome-teminal and type:

$ gjs hello.js
Hello, world
$

Easy, isn’t it? In this example you are executing the interpreter with the name of the file as argument, gjs opens the file and execute the instructions in it.

Lets see another venerable example, the hanoi tower.

// Hanoi
//
// hanoi.js
let hanoi = function(disc, src, aux, dest){
if(disc > 0){
hanoi(disc -1,src,dest,aux);
print('Move disc ' + disc + ' from ' + src + ' to ' + dest);
hanoi(disc -1, aux, src, dest);
}
};
hanoi(3, 'src', 'aux', 'dest');

Again, running from terminal

$ gjs hanoi.js
Move disc 1 from src to dest
Move disc 2 from src to aux
Move disc 1 from dest to aux
Move disc 3 from src to dest
Move disc 1 from aux to src
Move disc 2 from aux to dest
Move disc 1 from src to dest
$

if you have some experience in JavaScript (and I’m sure you do) you will notice there is a function that is not part of the standard language, you are right, the print() function; this is a built-in function that comes with default SpiderMonkey for its JavaScript Shell (be aware that SpiderMonkey does not provide host environments so APIs like DOM are not implemented).

Until now, we have been playing with the “standard” SpiderMonkey JavaScript engine but, what about using the libraries of the GNOME platform to make real desktop applications?. Let’s see how to do it.

Importing modules

In order to use a GNOME library (or a module added by GJS itself), GJS creates a built-in “object” to “import” a module into the application so you can use the objects defined in such module. Let’s see it with a simple example using the GLib’s file_test() utility function:

// File test example
//
// filetest.js
// 1. Imports GLib module (library)
const GLib = imports.gi.GLib;
// 2. Use file_test function from GLib module
// returns true if file exists
let fileExist = GLib.file_test('/home/miguel/.bashrc',
GLib.FileTest.IS_REGULAR);
if (fileExist)
print('File Exist!!!');

As in previous examples, if you run this in terminal:

$ gjs glibexample.js
File Exist!!!
$

Even though this is a very, very simple example, there are many new things to explore:

  1. The line const GLib = imports.gi.GLib; imports GLib library using gobject-introspection. We can now create objects or use functions and constant through GLib variable.
  2. The line let fileExist = GLib... calls the file_exist() function implemented in GLib library. Note I use another object ( GLib.FileTest.IS_REGULAR) as argument to the function.

As you can see, using the GNOME libraries in GJS is quite easy and convenient thanks to the amazing gobject-introspection technology. The challenge now is to “learn” how the objects and functions of this libraries are exposed to the language in GJS, for this, you can start here.

Somebody could say this can be done also in python using gobject-introspection but, as we all know, python has its own built-in modules and many of them collide in functionality with the ones defined in GNOME libraries, so using JavaScript as the minimum-platform programming language for GNOME makes totally sense now.

So, that’s all for now, in the following posts I will continue exploring more niceties of GJS and GNOME.