Archive for the 'Languages' Category

Taking the Pain Out of Complex Forms in Rails

The other day I was discussing Rails’ form processing behavior with Ben, when the topic of editing multiple associations in a single form came up. Effectively, he needed to be able to manipulate a collection of records associated with a parent via a has_many association. For each item in this collection, he wanted something like two drop down lists — nothing unreasonable. He said it was similar to recipe 13 from Advanced Rails Recipes — “Handle Multiple Models in One Form” — except that he had to use two fields instead of the one textfield, and it was proving to be surprisingly tough.

I know what you’re thinking: surely this can be extended to more than one form field per item without any problem? Up until I read the code myself a few months ago, I wouldn’t have thought it would be so difficult either — but it’s true. The parameter parsing code is quite quirky and, without reading the detail of the source, borderline unpredictable. I’ve had a few ideas for dealing with more complicated forms in Rails ever since I first ran into this issue. Only recently have I actually gotten around to doing something about it. Here’s an abridged version of an email I just sent to the rails-core mailing list:

Hi,

A colleague of mine recently ran into a related problem when dealing with collections of records in Rails forms, which prompted me to finally do something about the parameter parsing behavior. Now, while I’m sure we’re not the only ones hitting this wall, I’m aware that proposals to change to the parameter parsing semantics in Rails is likely to be met with a little caution, hesitation — possibly even terror. :) With that in mind, I’ve put up a plugin so everybody can give this a go without having to apply any nasty patches:

http://www.vector-seven.com/git/rails/plugins/form_collections.git

Please see the README (attached) for the full details.

Cheers,
Tom

This is a plugin which greatly simplifies the existing Rails parameter parsing code, and makes it a whole lot easier to deal with collections in your forms. I encourage all you Rails developers out there to take a look when you get the opportunity, I’d love to hear your opinions on this one. You can get a copy of the git repository using the following command:

$ git clone http://www.vector-seven.com/git/rails/plugins/form_collections.git

UPDATE: Here’s the contents of the README file:

> FormCollections
> ===============
>
> This plugin effectively rewrites UrlEncodedPairParser and provides the
> following features/changes:
>
> 1. The parameter parsing algorithm is much simpler
>
> There's all sorts of wacky stuff happening in the current implementation of
> UrlEncodedPairParser#parse. This plugin does away with that. A stack is no
> longer used during the parse. Parsing an Array vs. parsing a Hash is no longer
> all that different.  See lib/patch_url_encoded_pair_parser.rb.
>
> 2. Parsing "a[b][0][c]=6″ yields {”a” => {”b” => [{"c" => "6"}]}}
>
> Previously this would be parsed to: {”a” => {”b” => {”0″ => {”c” => “6″}}}}
>
> In other words, parameters that were formerly treated as hashes with a numeric
> index are now actually arrays.
>
> This is important, because the order in which form fields are present may be
> important to the back-end processing code. Here, the array in “b” will
> preserve the ordering specified — generating an Array rather than a Hash for
> numeric indices. Most other scenarios should essentially work as before, with
> the exception of a few error cases (e.g. parsing “a/b@[c][d[e][]=f” yields
> {”a/b@” => {”c” => {”d[e" => ["f"]}}} instead of {”a/b@” => {”c” => {}}}).
>
> The main problem here is that if an array is instantiated with a value at
> index 1000000, then we’ll have 999999 nil elements. I figure this can easily
> be worked around with an Array-like structure that consumes only as much memory
> as it needs but otherwise acts as an Array, or a hard limit set via
> configuration variable.
>
> 3. fields_for now treats Arrays properly …
>
> Example:
>
>  <% fields_for @post.comments do |comment_form, comment| %>
>    <%= comment.new_record? ? “” : comment_form.hidden_field(:id) %>
>    <%= comment_form.hidden_field :post_id %>
>    <%= comment_form.text_field :content %>
>    <hr />
>  <% end %>
>
> This will generate the following HTML for an array with two elements (one a new_record?, the other existing):
>
>  <input id=”comments_0_id” name=”comments[0][id]” type=”hidden” value=”1″ />
>  <input id=”comments_0_post_id” name=”comments[0][post_id]” type=”hidden” value=”1″ />
>  <input id=”comments_0_content” name=”comments[0][content]” size=”30″ type=”text” value=”a test comment” />
>  <hr />
>  <input id=”comments_1_id” name=”comments[1][post_id]” type=”hidden” value=”1″ />
>  <input id=”comments_1_content” name=”comments[1][content]” size=”30″ type=”text” value=”" />
>  <hr />
>
>
> Example
> =======
>
> Just install the plugin, and the new behavior should already be in effect.
>
> Copyright (c) 2008 Thomas Lee …, released under the MIT license
>

JVM Compiler Construction with Scala and BCEL, Part 1.5

The second part of my Scala compiler construction tutorial has been a long time coming. This post is, unfortunately, not the second part of the article — although that is coming soon. Honest.

Since part 1 was published, Scala 2.7 has been released which — among other things — introduced changes to the parser combinator library. Changes that meant the source code from part 1 will not compile in Scala 2.7. Sorry about that. Updated, working code can be found at the end of this post.

So what exactly has changed? Well, let’s see …

keyword() no longer discards its result

A bit of a refresher first:

In both Scala 2.6 and 2.7, the keyword implicit is called whenever you use a string in your “grammar rules”. For example:

def sum = expr ~ "+" ~ expr

Is the equivalent of:

def sum = expr.~(keyword("+").expr)

In Scala 2.6’s parser combinator library, the result of the keyword() call was actually the UnitParser — that is, a parser that would discard its result. At the time, that meant we could use the tilde operator (”~”) to create a sequenced parser and everything was fine:

def sum = expr ~ "+" ~ expr ^^ ((left : Expr, right : Expr) => Sum(left, right))

In 2.7, the keyword() implicit returns a Parser[String] rather than a UnitParser. This means we have to either deal with the newly introduced tokens as follows:

def sum = expr ~ "+" ~ expr ^^ ((left : Expr, op : String, right : Expr) => Sum(left, right))

Or alternatively …

Use <~ and ~> to indicate the important parts of a parse rule

Let’s start with something simple based on the 2.6 combinators:

def bracketExpr = "(" ~ expr ~ ")" ^^ ((e : Expr) => e)

Again, in 2.7 we know that keyword() is no longer a UnitParser, so we have to deal with it like so:

def bracketExpr = "(" ~ expr ~ ")" ^^ ((l : String, e : Expr, r : String) => e)

Alright, this compiles and does what we expect. But why should we keep those strings around if we don’t need them? They sure do clutter up the code a whole bunch.

<~ and ~> can be used to include or discard the result of a given parser. <~ builds a parser that takes the result of two parsers (the parsers to its left and right) and builds a parser that takes the result of both and discards the result of the one on the right. Conversely, ~> yields a parser that takes the result of both parsers and discards the result on the left.

So, using these two operators we can rewrite bracketExpr as follows:

def bracketExpr = "(" ~> expr <~ ")" ^^ ((e : Expr) => e)

Ah. Much better. :)

The ^^^ operator

I had to go digging in the Scala source code to work out what exactly this one does.

First, let’s take a look at some 2.6 code:

def simpleExpr = term * (
    "+" ^^ ((x : Expr, y : Expr) => Add(x, y)) |
    "-" ^^ ((x : Expr, y : Expr) => Sub(x, y))
)

In 2.6, this can parse zero or more repetitions of “term” interleaved by “+” and “-” (check out part 1 if you need a refresher on how the * combinator works). In 2.7 it’s a compile-time error because of the fact keyword() is no longer a UnitParser (are you seeing a pattern here? :)), and ^^ is trying to pass the resulting String on to the anonymous method in each case.

If we use the ^^^ operator here, we can effectively discard the result of the keyword parse, and build a parser that uses a simple anonymous method to parse the current pair of terms:

def simpleExpr = term * (
    "+" ^^^ ((x : Expr, y : Expr) => Add(x, y)) |
    "-" ^^^ ((x : Expr, y : Expr) => Sub(x, y))
)

Exactly what we’re after. This compiles and behaves as expected.

What else?

There may be more changes to the parser combinator library which I haven’t covered here, but I’m not going to go looking for any more changes since the updated code seems to work just fine. This should be enough to at least understand the updated code for the compiler described in part 1 without needing to deal with any cryptic compiler errors.

Finally, the new code!

Special thanks to Harshad for sending through working code for 2.7 ages ago which I never got around to posting here. This code, along with the Scala API docs, was used to figure out just what had changed since 2.6. The code below is derived from some code he sent to me a few months back.

I’m really sorry this has been so long in the making. I’ll try to get around to writing the “real” part two of this article. In the meantime, here’s the updated code. Thanks! Please post or email any comments or questions.

Implicits for the Masses

I just finished reading Tony Morris’s blog post on Scala implicits and saw the following comment:

To me, implicits look a lot like global variables, which is why I don’t like them.

Or maybe I missed something?

Uh, yep — you missed something :) I was going to reply in the comments to Tony’s post but as per usual it became far too long, so I’m posting it here instead.

Let’s try something a little less abstract than what was covered in Tony’s article. I haven’t actually tested any of this code to check that it compiles (lazy, lazy, lazy!), but it should be pretty straightforward & clarify what implicits can be used for:

class Person(name : String) {}
class Conversation(person1 : Person, person2 : Person) {
    def greet() = {
       println(person1.name + " says: Hello, " + person2.name)
       println(person2.name + " says: Oh, hello " + person1.name)
    }
}
implicit def stringToPerson(name : String) : Person = new Person(name)

With this implicit in effect, we can create a Conversation without even mentioning the Person class:

val conv = new Conversation("John", "Mary")
conv.greet()

See how we passed two strings to the Conversation constructor, even though it’s supposed to take two Persons?

Global variables don’t really come into it, it’s more about implicit type conversion.

Why would you do this? Well for one, it lets you create faux multimethods:

class FrameWrapper(frame : JFrame) {
    def title_=(s : String) = frame.setTitle(s)
    def visible_=(b : Boolean) = frame.setVisible(b)
}
implicit def wrapFrame(frame : JFrame) : FrameWrapper = new FrameWrapper(frame)

This means we can call FrameWrapper methods on a JFrame and the Scala compiler will figure out what we mean:

val frame = new JFrame
frame.title = "My Application"
frame.visible = true

Normally you’d have to call setTitle/setVisible at the second and third lines of the code above because JFrame doesn’t have any public attributes called “title” and “visible”. However, with the implicits in effect the Scala compiler will wrap your JFrame in a FrameWrapper instance to call that method. A weak example to be sure, but it really is a nice way to “scala-ize” any existing Java code. All this is statically checked too, so it won’t try to set your children on fire when you’re not looking.

Nifty eh?

Ruby Releases Are Scary (Or: How CI Can Save Your Ass)

In many open source software projects, full backwards compatibility is ensured between minor point releases (for example, 1.2.3 to 1.2.4). Generally speaking, these releases are made mostly to get important defect and/or security fixes to the public in a relatively timely manner. PHP is a notable exception to the rule: I haven’t been following development all that closely of late, but in the past it was not uncommon to break backwards compatibility between point releases.

Another major exception to the rule that hits a little closer to home is Ruby. In the past, backwards-incompatible changes have crept into point release changes — I’m uncertain as to whether or not this was intentional. However, the Ruby project also provides what’s known as a “patchlevel” release for each given point release. The patchlevel counts the number of patches applied to any given point release. Generally speaking, these seem to be bug and security fixes.

If you’re interested, the patchlevel release of your Ruby installation can be seen like so:

[ tom ] ~
$ ruby –version
ruby 1.8.x (YYYY-MM-DD patchlevel XXX) [i486-linux]

Anyway, over the past few days I’ve been watching the discussion leading up to patchlevel releases of Ruby 1.8.6 and 1.8.7. It’s been an interesting experience. You can follow the discussion from message #17499 here.

First there is an announcement that new versions of Ruby will drop in three days’ time. Shortly after this, the announcement that both versions are failing numerous rubyspecs (57 failing for 1.8.7!). Then a report that memory leaks may be present in both versions, followed by a report that one of the tests hang in Win32. Eventually a request to delay the release came through, along with a recommendation by Charles Nutter (the guy who brought us JRuby) to implement continuous integration.

I’m really surprised at a few things:

  • The original decision to make a release was based upon “I think current 1.8.6/1.8.7 is [more] stable than p230/p22″. Please, please tell me that the decision that the trunk is more stable than a previous release wasn’t based on a gut feeling. Please.
  • No continuous integration. It’s very important for software projects to maintain and continuously run a set of regression test. Otherwise, sooner or later they will break their users’ code.

Ruby is a great language and I applaud the work of the developers — maintaining a beast like the Ruby core for naught but love must be hard work. However, I have to say that I think their fumbling to get a stable release out the door on short notice — especially in the face of their recent security problems — is a concern for anybody relying on the Ruby code base. All that said, it sounds like the project is already taking steps in the right direction based on an earlier email to the list from Matz.

One day in the near future I’m sure that cutting a Ruby release won’t be quite so painful, but the lesson here is clear: Exercise your tests frequently — and ideally, automatically — or getting a stable release out the door might be nigh on impossible.

The Internals of Python’s IMPORT_NAME Bytecode

This was originally planned as a response to this post by Paul Bonser, but grew a little unwieldy (and his comment submission form seems to be broken?).

Effectively, Paul was (somewhat sleepily) mulling over the workings of the IMPORT_NAME bytecode. This bytecode is generated in response to Python code like the following:

import sys

And also for:

from foo import bar, baz

You’ll have to see the original post for the actual bytecode generated for this code, but Paul was asking why the latter syntax generates an IMPORT_NAME bytecode instruction which seems to do nothing at all with the fromlist, then generates additional IMPORT_FROM bytecodes that fetch the fromlist attributes from the parent module.

The documentation for __import__ somewhat solves this mystery:

Note that even though locals() and ['eggs'] are passed in as arguments, the __import__() function does not set the local variable named eggs; this is done by subsequent code that is generated for the import statement. (In fact, the standard implementation does not use its locals argument at all, and uses its globals only to determine the package context of the import statement.)

Essentially, when the IMPORT_NAME is executed for ‘from foo import bar, baz’, the __import__ builtin is called with the fromlist and a few other arguments (namely the globals() and locals() from the current frame of execution) to provide custom import handling for your Python programs. For example, you may want to prevent users of your program from writing scripts that import certain modules. I imagine Google’s App Engine might be using something like this to prevent access to certain evil or unavailable modules (but that’s just a wild, unfounded guess).

The code in Python/ceval.c for IMPORT_NAME seems to back this up (I’ve annotated the code with a few comments):


        case IMPORT_NAME:
            w = GETITEM(names, oparg);
            /* 1. LOCATE THE __import__ BUILTIN */
            x = PyDict_GetItemString(f->f_builtins, “__import__”);
            if (x == NULL) {
                PyErr_SetString(PyExc_ImportError,
                        “__import__ not found”);
                break;
            }
            Py_INCREF(x);
            v = POP();
            u = TOP();
            /* 2. BUILD THE LIST OF ARGUMENTS FOR __import__ USING THE fromlist, globals() AND locals() */
            if (PyInt_AsLong(u) != -1 || PyErr_Occurred())
                w = PyTuple_Pack(5,
                        w,
                        f->f_globals,
                        f->f_locals == NULL ?
                          Py_None : f->f_locals,
                        v,
                        u);
            else
                w = PyTuple_Pack(4,
                        w,
                        f->f_globals,
                        f->f_locals == NULL ?
                          Py_None : f->f_locals,
                        v);
            Py_DECREF(v);
            Py_DECREF(u);
            if (w == NULL) {
                u = POP();
                Py_DECREF(x);
                x = NULL;
                break;
            }
            READ_TIMESTAMP(intr0);
            v = x;
            /* 3. CALL __import__ WITH THE module name, fromlist, globals() AND locals() */
            x = PyEval_CallObject(v, w);
            Py_DECREF(v);
            READ_TIMESTAMP(intr1);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) continue;
            break;

So this answers the question of why IMPORT_NAME needs the fromlist in the first place: it is merely passed along to __import__ to make it available to custom import handling code. But why aren’t the fromlist attributes added to the namespace inside IMPORT_NAME? I’m guessing it was a design decision: we already have an opcode for adding elements to the namespace, so why have a special case for imports? Of course the details may be more involved than that, but it’s the most obvious explanation I can think of.

In any case, thanks for the thought-provoking post, Paul!

UPDATE: Seems my comment made it through to his blog after all. Sorry for the double-up!

Python 2.6a2: Compile ASTs from within Python code

I’m not going to go into too much depth because Georg Brandl has already covered it, but it’s an interesting topic. I couldn’t help but write a little entry about it. :)

A new alpha of Python has just been released, including a patch I wrote for compiling Python Abstract Syntax Trees down to bytecode. This means it’s now possible to manipulate ASTs from within your Python program, which lets you do all sorts of crazy things - like this, for example.

Piping this little program into itself yields the following:

$ ./python wacky.py <wacky.py
Bwahaha! I was once an Assign node!
Bwahaha! I was once an Assign node!

Neat huh?

Anyway, since then - on Neal Norwitz’s advice - I’ve started on an experimental patch for what I hope will one day be an optimizer for Python ASTs. Even though it’s early days, the possibilities offered by optimizing at the AST level are very interesting. For example, the (dirty, filthy, ugly, hack of a) patch I’m working on at the moment has support for optimizing this code:

if 1:
    'true'
else:
    'false'

Down to this (remember, no bytecode has been generated yet):

'true'

Very, very exciting stuff.

Anyway, I have a train to catch. More on this when I have more to show!

When Speed Matters

I’d be the first to tell you if, when confronted with a task that requires a degree of automation, you use a scripting language like Python, Ruby, Perl, Bash or some mix of the four. However, I recently had a problem that involved changing the permissions on a large number of files.

My initial approach used a small (10 lines or so) Bash script to traverse the filesystem hierarchy and change the permissions based on whether we were processing a file or a directory. The resulting script ran over more than 3000 files and directories in about a minute and a half. Which wasn’t exactly slow, but I had to run this script about twenty to thirty times throughout the day and it felt very unproductive to have to wait for a whole minute and a half before I could continue my work. So I did something crazy: I rewrote that little Bash program in C.

The resulting C program - of maybe 75 lines of code - finished in 1.3 seconds.

Initially I thought I had made a mistake, so I checked the processed files. They were all exactly as I expected them to be. I was astounded: I could execute this program almost 150 times before my old Bash solution finished even once! This decision made my day - the rest of my afternoon was much more productive. I even felt happier to know I wasn’t wasting so much time on something trivial and secondary to the actual task at hand.

Again, I’m not one to go preaching about how important performance is with respect to any given language - often it’s much, much easier to write a few Python/Ruby/Perl scripts and push data between them with some Bash glue. In this particular case, however, the choice of a lower-level language was clearly a massive win.

Even in retaining the pragmatic perspective, it really makes you wonder just how much time is lost to “inefficient” software stacks…

On Bloom Filters

I’ve got to admit that I don’t come from a hard core CS background (and I’m sure it shows in some of my articles on more complicated topics :P), but I know a little bit about data structures and algorithms. While I’m no expert on the topic of data structures, I was surprised that - up until now - I had never even heard of Bloom filters.

What are Bloom filters?
Let’s say you have a set of millions of records in a database. Running a query over such a database can be quite time consuming. It would be great if we a cheap way to determine if a given record is likely to be within the database without necessarily performing a query. Bloom filters to the rescue!

Rather than executing a complex database query, we can ask our Bloom filter whether or not a certain record exists. It will then respond with either a definitive “no” (i.e. the record is definitely not in the database) or a “maybe”. In the event our Bloom filter says “maybe”, we must (unfortunately) query the database to determine whether or not the record really exists.

While this may sound like double the workload for our poor application, querying the Bloom filter is likely to be very fast. The goal of the Bloom filter here is to reduce the number of times we actually hit the database, a way to determine the probability a given input exists in our data set. Bloom filters are also small in terms of memory usage, requiring nothing more than a simple bitfield.

A quick overview

Bloom filters primarily consist of a bitfield of size m and one or more (call it k) hash functions. The classic Bloom filter provides two main operations:

  1. add, which is used to add new records to the Bloom filter; and
  2. query, which is used to determine whether a record is likely to be found in the data set.

Starting out with a zero-value bitfield, each time we call add our hash functions are each called on the input record in turn to produce a set of k indices (one for each hash function). For each one of these indices, we set the corresponding bit in the bitfield.

To query this filter, we again generate k indices using our hash functions on the input record. Rather than setting the bits in the bitfield, we instead check each bit. If any one of the bits is not set, then there is zero chance our input record exists in the data set (a definitive “no”). Otherwise, if all k bits are set, we have a “maybe”.

Problems with the classic implementation

There’s one glaring problem with the classic Bloom filter: there are no deletions! If records in your source data set can be deleted, your Bloom filter may need to be regenerated (depending on your accuracy needs). There exists a variation on the classic filter which uses an array of counters instead of a bitfield. The add operation becomes a counter increment. This allows for a delete operation which, predictably, becomes a decrement of the counter. This variant trades memory for flexibility.

A reference implementation

I’m uploading a C reference implementation of a Bloom filter with 1 (super naive) hash function and a 32-bit-long bitfield. Hopefully there is somebody out there who finds it informative.

Download my crummy (but hopefully instructive!) reference implementation here.

WARNING I wrote this implementation from a quick read of the Wikipedia page, so if there are any CS geeks out there who can see I’m clearly doing something wrong, please tell me how wrong I am :)

Fixing Rails Nested Forms (or: HashWithIndifferentAccess is evil)

I’ve moved over to Shine’s Ruby on Rails team and, as such, have been exposed to a whole lot of Rails code over the past few weeks. Something I ran into a few weeks back was this bug, relating to a parsing bug in nested forms. I’ve submitted a series of patches, the last of which I hope to see in HEAD sometime over the next few days.

Anyway, the actual bug was caused by weirdo (and non-Hash-like) semantics in HashWithIndifferentAccess that causes certain types (Hash and Array) to be stored as a copy of the value passed in. The following code will give you an idea of the crazy logic that might result from such behavior:

def mktom(); {:name => 'Tom', :age => 23}; end

tom = mktom
people = {:tom => tom}
tom[:name] = ‘Thomas’
puts people[:tom][:name] # displays ‘Thomas’ - cool!
puts “The same object” if tom.object_id == people[:tom].object_id # displays ‘The same object’

tom = mktom
people = {:tom => tom}.with_indifferent_access
tom[:name] = ‘Thomas’
puts people[:tom][:name] # displays ‘Tom’ - wtf!
puts “Not the same object!” if tom.object_id != people[:tom].object_id # displays ‘Not the same object!’

The lesson learned from tracking down and fixing this bug?

  • Do not treat HashWithIndifferentAccess as though it were any old Hash. It has different semantics to Hash and may store copies of the keys and/or values instead of the original objects.
  • Do not nest HashWithIndifferentAccess instances in Hash instances unless you enjoy headaches. It’s so easy to think that HashWithIndifferentAccess is semantically identical to Hash (especially thanks to Hash#with_indifferent_access), but this assumption was the cause of two nasty, hard-to-find bugs in this instance.
  • When providing an API virtually identical to (and easily mistakable for) core Ruby classes, ensure that semantics are consistent with convention.

I’m not sure why they didn’t just override the reader for #[]. Maybe there’s more to that than I realize. Anyway, I’ve spent enough time thinking about this for tonight, time for bed. Sorry for the blog drought, I’m hoping to finalize a few more installments of the Ocaml series in along with the final part of my Scala/BCEL parser tutorial over the next few months. Stay tuned. :)

GTK Hello World in Six Different Languages

I’m still somewhat in holiday mode, so this entry is probably going to feel a little cheap for those of you following my more technical posts. I’m a big fan of GTK+ for user interfaces. If you don’t have the option or desire to use the Java platform and Swing, GTK+ is one of the better cross-platform user interface toolkits out there.

It’s high-level enough that it is easy to build quick, effective GUIs but low-level enough not to get in your way when you need to start messing around at the pixel level. GUIs can be built by hand using code, or designed using Glade and exported to an XML document to be loaded at runtime by any GTK+ binding. Currently it runs on Windows and Linux (the toolkit actually has its roots in GNOME) and has bindings for most popular programming languages. The only major downer is that Mac users are left out in the cold unless they go to the (herculean) effort of getting X11 up and running.

All the little differences between the various GTK+ bindings out there tend to get my goat when I move from one language to another. You would think that a GTK+ example in C could easily be translated to other languages without referencing documentation right? For one reason or another, the GTK+ bindings for other languages tend to diverge from the pleasant consistency of the C API to varying degrees. This post is all about those little differences that crop up even in the simplest applications: GTK’s take on “Hello World” in a few different languages.

C

C, being the language GTK+ is actually written in, is probably the most consistent with function naming across the different objects … the GTK_* and G_* macros are quite ugly though.

#include <gtk/gtk.h>

int main (int argc, char **argv) {
  GtkWidget *window;
  gtk_init(&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Hello, World");
  g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
  gtk_widget_show_all (window);

  gtk_main();
  return 0;
}

C#/Mono

GTK# adds stuff like the Application object and delegates to produce a “Hello World” example I had to go digging around in documentation for. Not too bad on the whole, though.

using Gtk;
using GtkSharp;

public class HelloWorld {
  public static void Main(string[] args) {
    Gtk.Window window = new Gtk.Window();
    window.Title = “Hello, World”;
    window.DeleteEvent += delegate { Application.Quit(); };
    window.ShowAll();
    Application.Run();
  }
}

Ocaml

The Ocaml bindings diverge from the original C API much more so than the other languages listed here, most likely due to design decisions that had to be made to provide a C binding to a functional language. My only real grumble is the inconsistency with window#event#connect vs window#connect. I’m guessing there was a technical reason for that, but it still irks me every time I see it.

let delete_event evt = false

let destroy () = GMain.Main.quit ()

let main () =
  let window = GWindow.window in
  let _ = window#set_title "Hello, World" in
  let _ = window#event#connect#delete ~callback:delete_event in
  let _ = window#connect#destroy ~callback:destroy in
  let _ = window#show () in
  GMain.Main.main ()
;;

let _ = main () ;;

Perl

Although I find writing Perl to be painful for everything but processing text files in a terminal, I found the Perl GTK bindings to be relatively straightforward.

use strict;
use Gtk2 '-init';

my $window = Gtk2::Window->new;
$window->set_title("Hello, World");
$window->signal_connect('delete-event', sub { Gtk2->main_quit; });
$window->show_all;
Gtk2->main;

Python

I’m more familiar with PyGTK than with other bindings, so this was a snap. Why they chose GtkObject.connect over GtkObject.signal_connect is a mystery and the pygtk.require(’…’) crap is a little weird, but aside from that there should be nothing surprising here (this is a good thing!).

import pygtk
pygtk.require('2.0')
import gtk

window = gtk.Window()
window.set_title('Hello, World')
window.connect('delete-event', gtk.main_quit)
window.show_all()
gtk.main()

Ruby

RubyGNOME provides a GTK+ binding for Ruby. Take an almost 1:1 port of the C API, take away the ugly casting macros, mix in closures for handling signals and Ruby really is one of the nicest ways to get intimate with GTK+.

require 'gtk2'

window = Gtk::Window.new
window.title = 'Hello, World'
window.signal_connect(:delete-event) { Gtk.main_quit }
window.show_all

Gtk.main

That’s all for now. There are many more language bindings for GTK+ out in the wild for languages like Lisp/Scheme, C++, Haskell and Erlang. If you’re looking around for a GUI toolkit, be sure to give GTK a go. There’s plenty of documentation available for all the bindings listed here, often with some very detailed and easy to follow tutorials.

UPDATE: Miguel and she suggested some changes to the C#/Mono and RubyGNOME examples.
UPDATE 2: Aristotle suggested an easier way to initialize the Perl GTK bindings.

Next Page »