On Jan 11, 2007, at 8:23 AM, Nathaniel Trellice wrote:

> Thanks for the ideas.
>
> What I was thinking of doing was writing a Ruby class (in C) which has
> the constants as class constants. This way, compiling the class will
> pull in the #defines from the C header file, and they'll be available
> within Ruby from my class. But, being new to ruby, I was hoping to  
> avoid
> having to figure out how to write a Ruby class in C at this stage  
> of my
> ruby development!
> Thanks again
> Nat
>
> -- 
> Posted via http://www.ruby-forum.com/.
>

It's really not as hard as you think.  In fact, I whipped this up in  
15 minutes (and that's because I had to look up the functions!)

If the set of constants is fixed, you need only create the C file  
once.  If not, then a script to generate your version of  
"rb_my_constants.c" with the right set of rb_define_const(...) lines  
would be a slightly better way to go than having to parse and  
generate the ruby module directly.  (Note, module rather than class  
since you didn't indicate there was any methods to share, but calling  
a C function as a Ruby method is almost just as easy.)

-Rob

rab:c $ mkdir my_constants
rab:c $ cd my_constants/
rab:my_constants $ head -100 my_constants.h rb_my_constants.c extconf.rb
==> my_constants.h <==
#define MY_CONSTANT     100
#define YOUR_CONSTANT   102
#define HIS_CONSTANT    0xCAFE

==> rb_my_constants.c <==
#include "ruby.h"

#include "my_constants.h"

static int id_my_constants;

VALUE mMyConstants;

void Init_my_constants()
{
     mMyConstants = rb_define_module("MyConstants");
     rb_define_const(mMyConstants, "MY_CONSTANT",   INT2NUM 
(MY_CONSTANT));
     rb_define_const(mMyConstants, "YOUR_CONSTANT", INT2NUM 
(YOUR_CONSTANT));
     rb_define_const(mMyConstants, "HIS_CONSTANT",  INT2NUM 
(HIS_CONSTANT));
}

==> extconf.rb <==
require 'mkmf'
create_makefile("my_constants")

rab:my_constants $ ruby extconf.rb
creating Makefile
rab:my_constants $ make
gcc -I. -I/opt/local/lib/ruby/1.8/i686-darwin8.8.1 -I/opt/local/lib/ 
ruby/1.8/i686-darwin8.8.1 -I. -O -pipe -I/opt/local/include -fno- 
common -O -pipe -I/opt/local/include  -fno-common -pipe -fno-common  - 
c rb_my_constants.c
cc -dynamic -bundle -undefined suppress -flat_namespace -L/opt/local/ 
lib   -L"/opt/local/lib" -o my_constants.bundle rb_my_constants.o  - 
lruby  -lpthread -ldl -lobjc
/usr/bin/ld: warning multiple definitions of symbol _setregid
/opt/local/lib/libruby.dylib(process.o) definition of _setregid
/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libpthread.dylib 
(setregid.So) definition of _setregid
/usr/bin/ld: warning multiple definitions of symbol _setreuid
/opt/local/lib/libruby.dylib(process.o) definition of _setreuid
/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libpthread.dylib 
(setreuid.So) definition of _setreuid

rab:my_constants $ ls -l
total 72
-rw-r--r--   1 rab  rab   3585 Jan 11 08:50 Makefile
-rw-r--r--   1 rab  rab     47 Jan 11 08:38 extconf.rb
-rwxr-xr-x   1 rab  rab  13296 Jan 11 08:51 my_constants.bundle
-rw-r--r--   1 rab  rab     83 Jan 11 08:38 my_constants.h
-rw-r--r--   1 rab  rab    402 Jan 11 08:49 rb_my_constants.c
-rw-r--r--   1 rab  rab   1304 Jan 11 08:51 rb_my_constants.o

rab:my_constants $ irb -rmy_constants
 >> MyConstants
=> MyConstants
 >> MyConstants.constants
=> ["MY_CONSTANT", "HIS_CONSTANT", "YOUR_CONSTANT"]
 >> MyConstants::MY_CONSTANT
=> 100
 >> MyConstants::YOUR_CONSTANT
=> 102
 >> MyConstants::HIS_CONSTANT
=> 51966
 >> MyConstants::HIS_CONSTANT.to_s(16)
=> "cafe"
 >> exit


Rob Biedenharn		http://agileconsultingllc.com
Rob / AgileConsultingLLC.com