How to do conditional compile for Ruby 1.9 in a C extension?

I’m working on updating RedCloth for Ruby 1.9. Since the output of
#singleton_methods changed from strings to symbols, I think I need a
conditional compile. Here’s what I tried:

#if RUBY_VERSION < 0x10900
if (rb_ary_includes(rb_funcall(self, rb_intern(“singleton_methods”),
0), btype)) {
#else
if (rb_ary_includes(rb_funcall(self, rb_intern(“singleton_methods”),
0), rb_str_intern(btype))) {
#endif

Sorry, ruby-forum cut off the rest of what I wrote. The above code
example is doing the first way for both 1.8 and 1.9. What’s the proper
way to detect the ruby version or the feature?

Thanks!
Jason G.

On Thu, Feb 19, 2009 at 12:21 PM, Jason G. [email protected]
wrote:

#endif

from version.h in Ruby 1.9
define RUBY_VERSION “1.9.2”
#define RUBY_RELEASE_DATE “2009-02-16”
#define RUBY_PATCHLEVEL -1
#define RUBY_BRANCH_NAME “trunk”

#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 9
#define RUBY_VERSION_TEENY 1
#define RUBY_RELEASE_YEAR 2009
#define RUBY_RELEASE_MONTH 2
#define RUBY_RELEASE_DAY 16

and for Ruby 1.8.6
#define RUBY_VERSION “1.8.6”
#define RUBY_RELEASE_DATE “2007-11-12”
#define RUBY_VERSION_CODE 186
#define RUBY_RELEASE_CODE 20071112
#define RUBY_PATCHLEVEL 5000

#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 8
#define RUBY_VERSION_TEENY 6
#define RUBY_RELEASE_YEAR 2007
#define RUBY_RELEASE_MONTH 11
#define RUBY_RELEASE_DAY 12

so I think that you want something like

#if RUBY_VERSION < ‘1.9.0’
do pre 1.9 stuff
#else
do 1.9 stuff
#end

Matz is careful to use Ruby version numbers which can be compared using
string comparison.

or

#if RUBY_VERSION_MAJOR = 1 && RUBY_VERSION_MINOR == 9
do 1.9 stuff
#else
do 1.8 stuff
#end

or some variant on those.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

It’s not working for me. In my C file I tested the presence of those
variables like so:

#ifdef RUBY_VERSION_MAJOR
printf(“RUBY_VERSION_MAJOR defined\n”);
#endif
#ifndef RUBY_VERSION_MAJOR
printf(“RUBY_VERSION_MAJOR NOT defined ******\n”);
#endif

and it outputs RUBY_VERSION_MAJOR NOT defined ******

Why aren’t the RUBY_VERSION constants defined?

did you include version.h?

On Thu, Feb 19, 2009 at 3:59 PM, Jason G. [email protected]
wrote:

and it outputs RUBY_VERSION_MAJOR NOT defined ******

Why aren’t the RUBY_VERSION constants defined?

Posted via http://www.ruby-forum.com/.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

version.h couldn’t be found. I’ve read that version.h is deprecated in
Ruby 1.9. There’s either got to be another way to detect the change or
a way to work around it. I’d just use map! to convert the strings to
symbols if I knew how to do it in C.

Matz is careful to use Ruby version numbers which can be compared using
string comparison.

Nice! I didn’t know that, so where I’d seen string comparisons on the
version number before, I just thought it was foolhardy.

Thanks for the help.

Jason

Jason G. wrote:

version.h couldn’t be found. I’ve read that version.h is deprecated in
Ruby 1.9. There’s either got to be another way to detect the change or
a way to work around it. I’d just use map! to convert the strings to
symbols if I knew how to do it in C.

I’m not saying this is the best way (maybe Nobu can provide a better
answer), but if you can be sure that mkmf.rb is being executed by the
same version of Ruby, then you could cook up a feature test in your
extconf.rb that would create a preprocessor symbol to test. Determine
what singleton_methods is doing, then call $defs.push to set a symbol:

 $defs.push("-DNEW_SINGLETON_METHODS")

Sorry, nobu, I didn’t follow you. Try again?

Hi,

At Fri, 20 Feb 2009 02:21:24 +0900,
Jason G. wrote in [ruby-talk:328775]:

I’m working on updating RedCloth for Ruby 1.9. Since the output of
#singleton_methods changed from strings to symbols, I think I need a
conditional compile. Here’s what I tried:

The output? You convert the argument.

#if RUBY_VERSION < 0x10900
if (rb_ary_includes(rb_funcall(self, rb_intern(“singleton_methods”),
0), btype)) {
#else
if (rb_ary_includes(rb_funcall(self, rb_intern(“singleton_methods”),
0), rb_str_intern(btype))) {
#endif

And #singleton_methods takes a flag, anything not only string
and symbol can be true.

Hi,

At Fri, 20 Feb 2009 18:58:55 +0900,
Jason G. wrote in [ruby-talk:328856]:

Sorry, nobu, I didn’t follow you. Try again?

Sorry, I misread the parentheses.

I’m working on updating RedCloth for Ruby 1.9. Since the output of
#singleton_methods changed from strings to symbols, I think I need a
conditional compile. Here’s what I tried:

It’s a problem indeed.

#if RUBY_VERSION < 0x10900
if (rb_ary_includes(rb_funcall(self, rb_intern(“singleton_methods”),
0), btype)) {
#else
if (rb_ary_includes(rb_funcall(self, rb_intern(“singleton_methods”),
0), rb_str_intern(btype))) {
#endif

Do you really need to know only if singleton method is defined,
not just self responds to it?

We may have to add a new macro in ruby.h.

I ended up sidestepping the whole issue completely and writing a new
accessor, #formatter_methods, that just returned singleton_methods.map!
{|method| method.to_sym }. The reasons for needing #singleton_methods
and not #respond_to? or #method_defined? are hard to explain, but you
can probably understand it fairly quickly by looking at the source:

A macro would’ve been nice, but it worked out okay for me anyway.
Thanks for your help!

Jason

Hi,

At Sat, 21 Feb 2009 04:48:49 +0900,
Jason G. wrote in [ruby-talk:328928]:

A macro would’ve been nice, but it worked out okay for me anyway.

Do you have any suggestion for the name? My candidate is
USE_SYMBOL_AS_METHOD_NAME.

Nobuyoshi N. wrote:

Hi,

Do you have any suggestion for the name? My candidate is
USE_SYMBOL_AS_METHOD_NAME.

Sounds great to me! Thanks!