Design of Gir-FFI¶ ↑
Basic Idea¶ ↑
Gir-FFI uses FFI
to read information from the GObject
Introspection Repository. Based on that it creates bindings for the information read.
Class and method creation¶ ↑
GirFFI::Builder
creates classes and modules at runtime and adds appropriate method_missing methods to them to generate methods and perhaps other classes when required.
The following options were discarded, at least for now.
-
Create classes and all of their methods at runtime. This would be very similar to the method chosen, but would concentrate all the overhead at start-up, some of which would be used for creating methods that will never get called.
-
Allow offline creation of ruby source generated from the GIR. This is still in interesting idea, but off-line source code generation is not really the Ruby way.
Method Naming¶ ↑
Probably, get_x/set_x pairs should become x and x= to be more Ruby-like. This should be done either by defining them as such directly, or by aliasing. Blindly going by the name leads to weird results thoough, like having x, x= and x_full= as a set. Also, some get_ or set_ methods take extra arguments. These probably shouldn’t become accessors either.
Boolean-valued methods could get a ? at the end.
This requires a lot more thought. For now, the full method names as defined in the GIR are used.
Ruby-GNOME Compatibility¶ ↑
Full Ruby-GNOME compatibility cannot be achieved automatically, since its object hierarchy differs from that of standard GObject: It puts Object
in the GLib
namespace, and defines signal_connect and friends as methods of GLib::Instantiable; In standard GObject
they are functions.
Possibly, compatibility enhancing code can be added for these specific exceptions.
Reference Counting¶ ↑
Because we can always make sure GObjects are unref’d when the Ruby object is GC’d, the mechanism of floating references actually gets in the way a bit. Therefore, when floating GObjects are constructed, GirFFI
will sink them. All GObjects can then safely be unref’d using a Ruby finalizer. GObjects obtained through other mechanisms than with a constructor will be ref’d once when wrapping them in a ruby object.
Bootstrapping Class Design¶ ↑
The interface to the GObject
Introspection Repository itself is also introspectable. The interface is specified in terms of structs and functions rather than objects and methods. For now, the hard-coded Ruby bindings for this don’t follow the introspected specification: Gir-FFI cannot bootstrap itself.
Object
initialization¶ ↑
Each constructor method is implemented in Ruby by a pair of new/initialize methods. For example, a constructor new_from_file
is implemented as a combination of the singleton method new_from_file
and the instance method initialize_from_file
. User-created subclasses override the appropriate initializer method and must call super with the appropriate arguments.
Here is an example of the generated pair of methods:
“‘ruby class Regress::TestObj def self.new_from_file(args) obj = allocate obj.__send__ :initialize_from_file, args obj end
def initialize_from_file(x) v1 = GirFFI::InPointer.from(:utf8, x) v2 = FFI::MemoryPointer.new(:pointer).write_pointer nil v3 = Regress::Lib.regress_test_obj_new_from_file v1, v2 GirFFI::ArgHelper.check_error(v2) store_pointer(_v3) end end