45

我有一个带有工厂方法的脚本,我想根据脚本是从 JRuby 还是从 Ruby 运行来返回某个类的不同实现。任何人对我如何从脚本内部分辨出差异有任何想法?

我最初的一些想法是:

  • 如果失败,尝试“包含 Java”并恢复到 Ruby 实现。这种方法行不通。无论我的开始/救援/结束如何,Ruby 都足够聪明,可以出错。

  • 用进程 ID 做一些愚蠢的事情。我宁愿避免这种情况,因为它总是感觉像一个黑客。

4

4 回答 4

52

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

于 2009-08-27T17:24:23.687 回答
47

正如这里已经说过的,有多种方法可以检测 JRuby。以下是按偏好排序的完整列表:

  1. 简单明了:

    RUBY_PLATFORM == "java"
    
  2. 这也可以用于其他实现。缺点是 MRI 1.8.6 和 1.8.7 还不支持 RUBY_ENGINE,所以我们需要定义的?查看:

    if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
    
  3. 如果您想知道的不仅仅是它是否是 JRuby:

    if defined? JRUBY_VERSION
    

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

  4. 最不喜欢的方式:需要 'java' 或需要 'jruby' 和救援。不应该使用。

于 2009-11-06T07:23:52.007 回答
6

我不太明白你的问题。您似乎混合了两个完全不同的抽象级别:Ruby 是一种编程语言,JRuby 是 Ruby 编程语言的编译器。你的程序是在 Ruby 中运行还是在 JRuby 中运行的问题是没有意义的:当它在 JRuby 中运行时,它也在 Ruby运行,因为 JRuby 是 Ruby 的实现。

这就像问“我怎么知道我是开福特还是汽车?”

如果您想知道您正在运行什么 Ruby 实现,那么您可以检查全局RUBY_ENGINE常量。它应该通用且唯一地识别您正在运行的引擎,尽管不幸的是它失败了,原因有以下三个:

  1. 在某些引擎上,它不会告诉您它正在运行什么引擎,例如在 YARV 上我希望RUBY_ENGINE'yarv',但它实际上是'ruby'。因此,它在“识别”部分失败了。
  2. 更糟糕的是:在 MRI 上,它也是 'ruby',这意味着它不仅不会告诉您正在运行什么引擎,而且还会有完全不同的引擎返回相同的值。IOW,它在“独特”部分也失败了。
  3. 最后但并非最不重要的RUBY_ENGINE是,它是相当新的,所以它还没有被所有引擎支持,这意味着它在“通用”部分失败了。

尽管如此,出于您的目的,例如

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

应该可以正常工作。

于 2009-08-29T12:14:31.407 回答
2

如果您正在调试 shell、irb、RVM 或某种类型的插件,例如 Ruby 文本编辑器插件,我更喜欢更详细的RUBY_DESCRIPTION.

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

于 2014-08-15T17:14:02.503 回答