
Thanks to everybody who wrote in with suggestions following on from my initial Ruby GNOME investigations yesterday.
After talking at cross purposes for some time in a bug report with a Ruby GNOME developer, I was pointed to a good example of how to do what I wanted: subclassing a GObject in Ruby.
This is something that the Mono Gtk# bindings do so well, I'd forgotten the required mechanics. Here's a simple subclass of button. I've highlighted the required magic in bold.
class MyButton < Gtk::Button
attr_accessor :hitcount
# tell the GLib object system this is a new type
type_register
def initialize(text)
super("label" => text)
self.hitcount = 0
end
# rather than overriding 'clicked', we must
# override the signal_do_clicked method
def signal_do_clicked(*args)
self.hitcount+=1
super
end
end
The type_register call registers the new class with the GLib type system (something the Mono bindings do for you automatically). The second key was knowing the name of the default signal handler, which turns out to be of the form signal_do_signalname.
So, to follow up yesterday, I hadn't found a bug, merely a gap in the documentation. Thanks to Masao Mutoh for taking the time to answer my questions.
For comparison, here's the same implementation in Gtk#. There are pros and cons of both languages. Ruby's succinct attr_accessor is balanced by the neat GObject-aware subclassing and the constructor inheritance of C#.
class MyButton : Button {
private int hitcount;
public MyButton (string text) : base (text)
{
hitcount = 0;
}
protected override void OnClicked ()
{
hitcount++;
base.OnClicked ();
}
public int HitCount {
get
{
return hitcount;
}
set
{
hitcount = value;
}
}
}