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

Discussion in 'Ruby' started by Jason Garber, Feb 19, 2009.

  1. Jason Garber

    Jason Garber Guest

    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
    --
    Posted via http://www.ruby-forum.com/.
     
    Jason Garber, Feb 19, 2009
    #1
    1. Advertising

  2. Jason Garber

    Jason Garber Guest

    Re: How to do conditional compile for Ruby 1.9 in a C extens

    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 Garber
    --
    Posted via http://www.ruby-forum.com/.
     
    Jason Garber, Feb 19, 2009
    #2
    1. Advertising

  3. [Note: parts of this message were removed to make it a legal post.]

    On Thu, Feb 19, 2009 at 12:21 PM, Jason Garber <> wrote:

    > 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
    >


    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
     
    Rick DeNatale, Feb 19, 2009
    #3
  4. Jason Garber

    Jason Garber Guest

    Re: How to do conditional compile for Ruby 1.9 in a C extens

    > 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
    --
    Posted via http://www.ruby-forum.com/.
     
    Jason Garber, Feb 19, 2009
    #4
  5. Jason Garber

    Jason Garber Guest

    Re: How to do conditional compile for Ruby 1.9 in a C extens

    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?
    --
    Posted via http://www.ruby-forum.com/.
     
    Jason Garber, Feb 19, 2009
    #5
  6. Re: How to do conditional compile for Ruby 1.9 in a C extens

    [Note: parts of this message were removed to make it a legal post.]

    did you include version.h?

    On Thu, Feb 19, 2009 at 3:59 PM, Jason Garber <> wrote:

    > 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?
    > --
    > 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
     
    Rick DeNatale, Feb 19, 2009
    #6
  7. Jason Garber

    Jason Garber Guest

    Re: How to do conditional compile for Ruby 1.9 in a C extens

    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.
    --
    Posted via http://www.ruby-forum.com/.
     
    Jason Garber, Feb 20, 2009
    #7
  8. Jason Garber

    Tim Hunter Guest

    Re: How to do conditional compile for Ruby 1.9 in a C extens

    Jason Garber 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")

    --
    RMagick: http://rmagick.rubyforge.org/
     
    Tim Hunter, Feb 20, 2009
    #8
  9. Hi,

    At Fri, 20 Feb 2009 02:21:24 +0900,
    Jason Garber 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.

    --
    Nobu Nakada
     
    Nobuyoshi Nakada, Feb 20, 2009
    #9
  10. Jason Garber

    Jason Garber Guest

    Re: How to do conditional compile for Ruby 1.9 in a C extens

    Sorry, nobu, I didn't follow you. Try again?
    --
    Posted via http://www.ruby-forum.com/.
     
    Jason Garber, Feb 20, 2009
    #10
  11. Hi,

    At Fri, 20 Feb 2009 18:58:55 +0900,
    Jason Garber 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.

    --
    Nobu Nakada
     
    Nobuyoshi Nakada, Feb 20, 2009
    #11
  12. Jason Garber

    Jason Garber Guest

    Re: How to do conditional compile for Ruby 1.9 in a C extens

    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:
    http://github.com/jgarber/redcloth/commit/c941af12fff3f93154578c160aed0727be98dff0

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

    Jason
    --
    Posted via http://www.ruby-forum.com/.
     
    Jason Garber, Feb 20, 2009
    #12
  13. Re: How to do conditional compile for Ruby 1.9 in a C extens

    Hi,

    At Sat, 21 Feb 2009 04:48:49 +0900,
    Jason Garber 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.

    --
    Nobu Nakada
     
    Nobuyoshi Nakada, Feb 22, 2009
    #13
  14. Jason Garber

    Jason Garber Guest

    Re: How to do conditional compile for Ruby 1.9 in a C extens

    Nobuyoshi Nakada wrote:
    > Hi,
    >
    >
    > Do you have any suggestion for the name? My candidate is
    > USE_SYMBOL_AS_METHOD_NAME.


    Sounds great to me! Thanks!
    --
    Posted via http://www.ruby-forum.com/.
     
    Jason Garber, Feb 22, 2009
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alec S.
    Replies:
    10
    Views:
    10,194
    Alec S.
    Apr 16, 2005
  2. Nagaraj
    Replies:
    1
    Views:
    882
    Lionel B
    Mar 1, 2007
  3. timjowers
    Replies:
    7
    Views:
    4,357
    heyjude
    Feb 2, 2011
  4. Sascha Ebach
    Replies:
    0
    Views:
    130
    Sascha Ebach
    Feb 2, 2006
  5. Iñaki Baz Castillo
    Replies:
    2
    Views:
    229
    Iñaki Baz Castillo
    Apr 20, 2011
Loading...

Share This Page