46

I have a script with a factory method that I would like to return a different implementation of some class depending on whether or not the script is running from JRuby or Ruby. Anyone have any ideas on how I could tell the difference from inside my script?

Some initial thoughts I had were:

  • Attempt to 'include Java' and rescue back to the Ruby implementation if it fails. This method doesn't work. Ruby's smart enough to error out regardless of my begin/rescue/end.

  • Do something goofy with process IDs. I'd rather avoid this, since it always feels like a hack.

Nakilon
  • 34,866
  • 14
  • 107
  • 142
pastorius
  • 633
  • 5
  • 8

4 Answers4

54

I believe you can check the RUBY_PLATFORM constant.

Saturn
  • 17,888
  • 49
  • 145
  • 271
JesperE
  • 63,317
  • 21
  • 138
  • 197
49

As already have been stated here, there are multiple ways to detect JRuby. Here's the complete list, sorted by preference:

  1. Simple and straightforward:

    RUBY_PLATFORM == "java"
    
  2. This can be used for other impls as well. The downside is that MRI 1.8.6 and 1.8.7 do not support RUBY_ENGINE yet, so we need the defined? check:

    if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
    
  3. If you wish to know a bit more than just whether it's JRuby or not:

    if defined? JRUBY_VERSION
    

    JRUBY_VERSION is only defined in JRuby and in provides the short version info, like "1.5.0.dev"

  4. Least favorite way: require 'java' or require 'jruby' and rescue. Should not be used.

  • 2
    Actually, you must provide parenthesis for the second version so it would be if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' – Tyler Brock Dec 06 '12 at 15:51
  • The last option isn't as bad as it sounds. If you were going to test for JRuby and then require 'java' anyway (and if you weren't, let's face it, why even bother detecting JRuby), then adding a rescue doesn't seem so bad. – Hakanai Aug 29 '13 at 23:20
6

I don't quite understand your question. You seem to be mixing two completely different abstraction levels: Ruby is a programming language, JRuby is a compiler for the Ruby programming language. The question whether your program is running in Ruby or in JRuby just plain doesn't make sense: when it's running in JRuby, it is running in Ruby, because JRuby is an implementation of Ruby.

It's the same as asking "how can I tell if I'm driving in a Ford vs. a car?"

If you want to know in what Ruby implementation you're running, then you can check the global RUBY_ENGINE constant. It is supposed to universally and uniquely identify the engine you are running on, although it unfortunately fails for three reasons:

  1. on some engines, it doesn't tell you what engine it is running on, for example on YARV I would expect RUBY_ENGINE to be 'yarv', but it is actually 'ruby'. So, it fails at the "identify" part.
  2. even worse: on MRI, it is also 'ruby', which means that not only does it not tell you what engine you are running on, but there also totally different engines that return the same value. IOW, it also fails at the "unique" part.
  3. and last but not least, RUBY_ENGINE is fairly new, so it is not yet supported by all engines, which means it fails at the "universal" part.

Still, for your purposes something like

if defined? RUBY_ENGINE && RUBY_ENGINE == 'jruby'

should work fine.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • if defined? RUBY_ENGINE and RUBY_ENGINE == 'jruby' – Mike Li Feb 16 '13 at 15:19
  • 1
    To use your analogy, sometimes you need to know if your car is a ford. For example you many need to know if you want to support a native extension not supported by jruby in your code. – Will May 14 '13 at 11:36
  • Good point about RUBY_ENGINE being relatively new. Was there an older version of JRuby which didn't have it? – Hakanai Aug 29 '13 at 23:22
  • The question **can** make sense. For instance I'm developing an application where the depending on the Platform different implementations of libraries are use (Java- vs. Pure Ruby). Hence I'm testing `JRUBY_VERSION` to isolate the platform dependent code. – user1934428 Jul 05 '23 at 10:49
2

If you're debugging in the shell, irb, RVM, or some type of plugin like Ruby text editor plugins I prefer the more verbose RUBY_DESCRIPTION.

If you're trying to run some code based on whether you're running JRUBY or not, other constants mentioned are good: RUBY_ENGINE, JRUBY_VERSION or RUBY_PLATFORM.

iconoclast
  • 21,213
  • 15
  • 102
  • 138
vicmunoz
  • 21
  • 2