ruby
fig 1 - Testing of Ruby FFI wrappers for GSL against results from direct C calls
Wrapping FFI based ruby calls to GSL requires handling 1000+ functions with their various features of calling arguments and returns. That's an error prone business and I wanted to have tests that would automatically check that my wrappers results match up with results from calling GSL functions within a C program.[1]
This made me depressed.
I was looking at having to hand code C programs to generate answers from functions like, "gsl_complex_sqrt_real(2.0)" (which is (1.4142135623731,0.0) by the by). And then another set of Ruby programs that would cross check those answers against my FFI wrappered calls to GSL. That's a lot of extra coding (see fig 1 for an individual test).
I chewed on this for several days, and when I had time to work on GSL4r again, I decided to add a GSL4r::Harness module, which would include the following methods:
- write_c_tests
- compile_c_tests
- run_c_tests
Added automatically generated method wrappers for calls into the GSL library using the object itself:
rgslffi GSL4r is a set of wrapper routines I'm creating around GNU Scientific Library (GSL) mathematical routines using the Foreign Function Interface (FFI) library for Ruby/JRuby. Using FFI helps avoid tying GSL only to the C based Ruby interpreters and potentially will make the library universally available across all Ruby implementations. Something we'd like to have while using JRuby for the ATA.
While working on rgslffiGSL4r, I needed to define a mapping for the gsl_complex struct (we'll ignore for now that gsl_complex is potentially platform dependent).
Here's my attempt:
class GSL_Complex < ::FFI::Struct layout :dat, [:double, 2] R = 0 I = 1 def real() return self[:dat][R] end def imag() return self[:dat][I] end def equals( a ) return ( a[:dat][R] == self[:dat][R] && a[:dat][I] == self[:dat][I] ) end def set( r, i ) self[:dat][R] = r self[:dat][I] = i return self end def set_real( r ) self[:dat][R] = r end def set_imag( i ) self[:dat][I] = i end def to_s() return "(#{self[:dat][R]},#{self[:dat][I]})" end end
I was stumped for a few hours on passing FFI::Structs into external routines, luckily, this post, 'Functions returning structures' (groups/google/ruby-ffi), tipped me off by showing how to return a struct by value:
From the C code:
... typedef struct { int r, g, b, a; } ALLEGRO_COLOR; ...

credit:C G-K
Now available, the 1.1.5 release of log4r (See: http://log4r.rubyforge.org or gem install -r log4r)
Addressed in 1.1.5:
FileOutputter no longer truncates files by default
Syntax fixed up in GDC/NDC classes to work in Ruby 1.9 as well as 1.8
I'm also quite happy about the move to hosting ruby gems at http://gemcutter.org. Its helped me become aware of how widely log4r is a pre-requisite for other software. Since I started new releases last September (2009), it was downloaded over 21,000 times, with the 1.1.4 release on January 12, 2010, downloaded 12,000+ times alone.
*nervous*