我如何判断自己是在运行JRUBY还是Ruby?

46

我有一个工厂方法的脚本,我希望根据脚本是否从JRuby或Ruby运行来返回某个类的不同实现。 有没有任何想法可以告诉我如何在我的脚本内部区分它们?

我最初的想法是:

  • 尝试“包含Java”,并在失败时回退到Ruby实现。这种方法不起作用。 Ruby聪明到足以在begin / rescue / end之外引发错误。

  • 使用进程ID处理一些滑稽的事情。 我宁愿避免这种方法,因为它总感觉像是一个hack。

4个回答

54

我相信你可以检查RUBY_PLATFORM常量。


1
没错。在 JRuby 和其他操作系统下,它是“Java”。 - Chuck
确实。对我来说足够好了。非常感谢! - pastorius
@Chuck:感谢您的验证。我手头没有安装JR​​uby。 - JesperE

49

如已在此处说明,有多种方法可以检测JRuby。以下是按首选项排序的完整列表:

  1. 简单而直接:

    RUBY_PLATFORM == "java"
    
    这也可以用于其他实现。不足之处在于MRI 1.8.6和1.8.7尚不支持RUBY_ENGINE,因此我们需要使用defined?检查:
    if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
    
    如果你想了解更多信息而不仅仅是是否为JRuby:
    if defined? JRUBY_VERSION
    

    JRUBY_VERSION仅在JRuby中定义,并提供短版本信息,如“1.5.0.dev”。

    最不喜欢的方法:使用require 'java'或require 'jruby'并进行异常捕获。不应使用。


2
实际上,你必须在第二个版本中提供括号,这样它就可以是 if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'。 - Tyler Brock
最后一个选项并不像听起来那么糟糕。如果你本来就要测试JRuby,然后无论如何都需要require 'java'(如果你不这样做,让我们面对现实,为什么还要检测JRuby),那么添加一个rescue似乎并不那么糟糕。 - Hakanai

6
我不太理解你的问题。你似乎混淆了两个完全不同的抽象级别:Ruby 是一种编程语言,JRuby 是 Ruby 编程语言的编译器。问题是你的程序是在 Ruby 运行还是在 JRuby 运行,这个问题根本就没有意义:当它在 JRuby 中运行时,它就是在 Ruby 中运行,因为 JRuby 是 Ruby 的一个实现。
这就好比问“我如何知道我是开着福特还是汽车?”一样。
如果你想知道你正在使用哪个 Ruby 实现,那么可以检查全局的 RUBY_ENGINE 常量。它应该能够普遍而独特地标识你正在运行的引擎,尽管不幸的是,它有三个失败之处:
1. 在某些引擎上,它并没有告诉你它正在运行的是什么引擎,例如在 YARV 上,我期望 RUBY_ENGINE 应该是 'yarv',但实际上是 'ruby'。因此,在“标识”方面失败了。 2. 更糟糕的是,对于 MRI(Matz’s Ruby Interpreter),它也是 'ruby',这意味着它不仅没有告诉你你正在运行的是什么引擎,而且还有完全不同的引擎返回相同的值。换句话说,在“独特”方面也失败了。 3. 最后但并非最不重要的是,RUBY_ENGINE 是相对较新的,因此还没有被所有引擎支持,这意味着它在“普遍”方面也失败了。
尽管如此,对于你的目的来说,类似以下内容可能会有帮助:
if defined? RUBY_ENGINE && RUBY_ENGINE == 'jruby'

应该可以正常工作。


如果已定义?RUBY_ENGINE 并且 RUBY_ENGINE == 'jruby' - Mike Li
1
使用您的比喻,有时候您需要知道您的汽车是否是福特。例如,您可能需要知道是否要在您的代码中支持jruby不支持的本地扩展。 - Will
关于 RUBY_ENGINE 相对较新的观点很好。之前的 JRuby 版本是否没有它? - Hakanai
这个问题是有意义的。例如,我正在开发一个应用程序,在不同的平台上使用不同的库实现(Java vs. Pure Ruby)。因此,我通过测试JRUBY_VERSION来隔离与平台相关的代码。 - user1934428

2
如果你在shell、irb、RVM或者一些像Ruby文本编辑器插件这样的插件中进行调试,我更喜欢使用更详细的。
如果你想根据是否运行JRUBY来运行一些代码,其他提到的常量也很好:、或者。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接