Portrait of Edd Dumbill, taken by Giles Turnbull

Subscribe to updates

Feed icon Atom or RSS

or get email updates

What I make

expectnation
a conference management web application


XTech Conference
a European web technology conference

Beginnings with Ruby GNOME

A while back I started porting the GTK examples from Mono: A Developer's Notebook to IronPython and Boo, the results of which are available in my Subversion repository.

Although I've not finished that task yet, I thought I'd investigate the state of the Ruby GNOME bindings by porting those same examples. They have the advantage of increasing gently in complexity.

Before I go on, you can find the work in progress posted in the ruby-gnome/monodn branch of my Subversion repository.

Now for a few observations. At the basic level, Ruby GNOME has a lot in common with all the other GNOME bindings out there. One distinguishing feature however is signal handlers, which take a Ruby closure as an argument. Look at this handler for closing the window, for example:

w = Gtk::Window.new("My Window")
w.signal_connect("delete_event") { Gtk.main_quit }

This is fine for simple handlers. Developers wanting to reuse handlers might wish to specify a method here to use. The best way of doing this I've found is:

def my_handler(but)
   ...
end

button.signal_connect("changed", &method(:my_handler))

This involves a little bit more magic, as you can see.

I've also run into an unexpected barrier with subclassing and the class default signal handler. The subclassing example from the Mono Notebook shows an example of overriding the clicked method of a Button. In C# this looks like this:

class MyButton : Button {
...
protected override void OnClicked ()
{
  hitcount++;
  base.OnClicked ();
}

In Ruby I would write this:

class MyButton < Gtk::Button
...
def clicked
  self.hitcount += 1
  super
end

However, when you click the button it's clear the overridden method isn't being called. I've filed a bug with what I think is the underlying problem. In this instance, I worked round it by adding a signal handler in the constructor:

self.signal_connect("clicked") { |b| b.hitcount += 1 }

At the moment it feels like I'm writing rather C-like Ruby, rather than it being idiomatic. But then again, I am porting examples from C# in as literal manner as possible, in order to facilitate comparison.

blog comments powered by Disqus


You are reading the weblog of Edd Dumbill, writer, programmer, entrepreneur and free software advocate.
Copyright © 2000-2012 Edd Dumbill