Ruby编程语言的许多解释器和运行时

本文概述

介绍

正如Ruby Gem有许多阴影一样, Ruby解释器也有多种实现。

最常用的Ruby解释器是参考实现Ruby MRI, 它由Ruby的创建者(Yukihiro Matsumoto)和Ruby核心团队以C语言开发。

我们的Ruby on Rails招聘指南提到, 通过使用备用Ruby解释器, 可以潜在地解决或避免Rails中的某些缺点。本文展示了当今可用的各种现有的Ruby解释器实现和运行时, 并讨论了每种实现的优缺点。

Ruby解释器和运行时的列表,包括mruby,JRuby,RubyMotion,Rubinius和Ruby MRI

Ruby版本历史记录(及其对替代实现的影响)

可悲的是, 没有等效于Ruby的Python语言参考(ISO / IEC 30170:2012描述了Ruby 1.8 / Ruby 1.9, 但没有针对Ruby 2.x的相应规范)。在没有任何这样的语言规范的情况下, Ruby实现者通常依赖于社区驱动的RubySpec, 该规范通过可在任何Ruby解释器中运行的测试来指定Ruby语言的预期行为。因此, Ruby实现者使用RubySpec来验证其Ruby实现与事实标准的行为符合性。

由于缺乏正式规范, 因此Ruby的新版本通常仅与Ruby MRI的新版本相对应。值得注意的是, 有一个未解决的问题, 讨论了将Ruby(语言)与Ruby MRI分离的设计过程。

但是, 考虑到当前在Ruby语言和MRI参考实现之间的紧密联系, 替代Ruby实现的开发人员有时很难跟上每个新MRI版本中引入的语言更改。

在Ruby 1.8和Ruby 1.9之间的过渡中, 这从未像现在这样难。在2007年, 为了清理和整合Ruby的语法(自Ruby 1.0发行以来的十年发展, 该语言), Ruby核心团队发布了Ruby 1.9.0, 该版本将许多向后不兼容的特性引入了该语言。 。结果, 并不是所有的Ruby实现都投入了使语法从1.8跳到1.9所需的精力。因此, 社区不再使用几种基于1.8的Ruby实现, 但是你仍然可以在网上找到它们, 也可以由Ruby的老手谈论。

遵循语义版本化原则, 每年圣诞节都会发布新版本的Ruby MRI。 Ruby 2.0(2013年发布)和2.1(2014年发布)各自引入了Ruby开发人员可以利用的其他语言功能, 而不会丧失与Ruby 1.9的向后兼容性。

为什么要使用替代的Ruby实现? MRI怎么了?

有许多替代的Ruby实现, 支持各种用例和环境。 Java Enterprise环境。移动应用程序。 JavaScript实现。低CPU / RAM机器。除了支持这些用例之外, 根据应用程序的特性, 替代实现有时还可以进一步提高速度或提高内存利用率。

长期以来, 许多Ruby on Rails开发人员都使用Ruby Enterprise Edition(REE)代替了MRI, 与当时的MRI版本相比, 利用REE中更好的内存管理技术。 (REE随后于2012年停产。)

虽然MRI是Ruby的默认实现, 但不一定适合所有环境和场景。例如, MRI的并发支持不如JRuby或Rubinius。另外, 尽管MRI的内存和垃圾收集方案在不断改进, 但它们仍然存在一些问题。

接下来的Ruby实现调查旨在帮助你选择最适合你项目的运营目标和约束的解释器。

Matz的Ruby解释器(MRI)/ CRuby

MRI是由Ruby核心团队(由yukihiro Matsumoto(” Ruby的创建者” Matz”领导)以C语言编写的, 它是Ruby的参考实现, 它是事实上的标准。例如, 如果操作系统供应商将Ruby版本作为操作系统安装软件的一部分, 则通常是MRI版本。与其他Ruby实施相比, MRI受益于薪酬更高的核心团队成员, 还有希望改善Ruby生态系统的人员或公司投入的专用资源。

每年圣诞节都会发布一个新版本的Ruby MRI, 除了标准库的更改外, 该版本通常还实现新的语言功能。通常首先基于Ruby核心开发人员邮件列表中的讨论在Ruby MRI中实现功能。其他Ruby实现有时甚至落后数年。

JRuby

JRuby是在Java虚拟机(JVM)之上实现的Ruby版本。随着基于Java的语言能够在JVM之上运行, 而不仅仅是Java语言(我正朝着Clojure和Scala的方向发展), 基于JVM的Ruby实现可能会越来越流行。

JVM中的Ruby也意味着Ruby可以在Java可以运行的任何地方运行(例如Android手机, 例如使用Ruboto)。另外, 由于JVM的互操作性, JRuby代码可以利用Java平台, 包括标准库和第三方库。

JRuby对于将基于Rails的解决方案引入仅Java的部署环境, 将Rails应用程序打包为.war文件以部署到Tomcat容器或作为Web前端的一部分运行的Java applet也很有用。 , 例如。

但是, 对于那些不习惯JVM的人, JRuby带来了与JVM相关的标准问题, 例如Ruby解释器的启动缓慢, 如果你使用的是第三方Java库, 则调试CLASSPATH问题, 更大的内存使用量以及现在你的代码需要在编写时考虑线程安全性注意事项。

此外, JRuby并未实现Ruby的某些功能(C API, 以及Ruby强大的自省工具之一, ObjectSpace模块)。

综上所述, 使用JVM的优势可能胜过某些情况或项目的劣势。 JVM允许进行许多性能优化, 例如打开JIT编译器或使用本机Java对象和API。

作为一个引人注目的JRuby用例的示例, 我的一位前同事曾经遇到过CPU密集型问题, 他最初使用Ruby 1.9.3中的线程解决了该问题。当他切换到JRuby并使用Java的java.util.concurrent.Executors时, 他看到此操作的性能提高了多个数量级(快几万倍)。在这里查看他的实验。

Rubinius

Rubinius是Ruby的一种实现, 它在低级虚拟机(LLVM)之上为动态语言实现了通用运行时。使用这种基础架构和JIT编译器技术, Rubinius可以比MRI花费更少的开销来运行Ruby代码。

Rubinius也是使用尽可能多的Ruby构建的, 以使解释器/运行时的开发更快, 更容易。

有趣的事实:RubySpec最初是在实现Rubinius的过程中产生的。

与JRuby一样, Rubinius包含JIT编译器, 更好的内存管理以及比Ruby MRI更成熟的虚拟机。但是, 与JRuby不同, Rubinius支持Ruby C库, Rubinius的基础是用C ++而不是Java编写的。

当你需要在Rails服务器上获得高性能而又没有学习曲线或JRuby的其他缺点时, Rubinius可能是很好的中间立场。

mruby

mruby被设计为Ruby的可嵌入版本(支持Ruby 1.9.3)。使用mruby, 你可以在本机应用程序中提供Ruby作为脚本/自动化语言, 将其用于游戏脚本, 甚至用于对Raspberry Pi等微控制器板进行编程。

如果你的平台有严格的资源限制, 那么mruby可能只是适合你的Ruby解释器。 mruby还用于:

  • 构建iOS应用程序(作为RubyMotion的竞争对手, 如下所述)
  • 将Ruby嵌入iOS应用中, 以提高开发速度
  • 为最终用户提供用于自动化目的的嵌入式脚本语言

随着物联网越来越成为现实, 家庭自动化逐渐发展起来, 超便携式(且功能相对强大)的计算机越来越普遍, 要支持的目标平台的格局也日益多样化。 mruby使使用与台式机上使用的相同的生产语言可以做到这一点。

Opal

Opal是将Ruby变成JavaScript的编译器。

随着Coffeescript的兴起, 开发人员正在学习不必键入JavaScript即可获取JavaScript。虽然Coffeescript具有其优势, 但使用足够长的时间, 肯定会遇到你不喜欢该语言的问题。

输入Opal:输入Ruby, 获取Javascript。很酷

Opal努力与其他Ruby实现尽可能保持一致, 因此也针对RubySpec的子集进行了测试。但是, 由于JavaScript和JavaScript运行时的性质, 确实存在一些不兼容性。例如, Opal中的字符串和符号相等, 并且Opal不提供任何线程或Shell执行机制。

Opal可以独立运行, 也可以用作Rails资产管道的一部分(例如, 自动将somefile.js.rb文件转换为JavaScript)。

也许你有一个非常适合JavaScript的异步并发模式的问题域(例如小型Node.js服务), 但是想要Ruby空间中的语言或某些宝石。在这种情况下, Opal可能是你的理想选择。

或者, 也许你想编写一个全栈的Ruby Web应用程序。使用Opal, 你可以。让一个Ruby解释器运行你的服务器端Ruby代码, 然后让Opal生成JavaScript以在客户端上运行。

Opal意识到你可能会与其他JavaScript API(例如DOM或Node.js)进行交互。因此, 它可以轻松过渡到JavaScript, 并在jQuery之类的常见JavaScript库上提供一些Ruby语法糖。

Opal以JavaScript为中心的特性既有优势也有劣势。不利的一面是, Opal的运行时是JavaScript运行时, 而Opal则受JavaScript设计决策的影响。因此, 如果你正在寻找一个很好的Ruby实现来编写小型Shell脚本, 或者正在为Rails应用寻找更好的Ruby运行时, 那么Opal可能不是你的最佳选择。

RubyMotion

RubyMotion既是(a)一个Ruby实现(使用Objective-C和Cocoa编写), 又是(b)一组语言绑定, 以便开发人员可以通过Ruby访问Cocoa API。

RubyMotion是一种商业产品, 使你可以用Ruby编写Cocoa本机应用程序。 RubyMotion 2.0允许你使用Ruby编写iOS和Mac OS X应用程序, 而RubyMotion 3承诺将为Android提供相同的支持。

RubyMotion实现Ruby语言的1.9版。

无效的实现

自从首次引入Ruby以来, 多年来, 一些已被废弃或停止使用的Ruby实现, 例如:

  • Ruby企业版(REE)。 REE是Phusion Passenger员工的MRI 1.8的分支, 它为Web开发人员实现了许多内存和垃圾收集方面的改进。几年来, 这是为生产Rails站点部署的默认Ruby实现。不过, 它从未针对Ruby 1.9或Ruby 2.0进行过更新, 最终于2012年停产。
  • IronRuby。 IronRuby是用C#编写的基于Microsoft .NET的Ruby, 并且有一段时间该项目由Microsoft资助。 IronRuby在2011年被放弃, 最后一次支持Ruby 1.8.6。

本文总结

在Ruby环境中, 可以选择各种各样的运行时和解释器。对于大多数Ruby项目, Ruby参考实现(Ruby MRI)仍然是首选的解释器。但是, 根据你的功能和技术目标以及约束条件, 替代的Ruby实现可能非常适合你的项目。

MRI作为Ruby的参考实现, 它更快地获得了新的语言功能, 具有足够好的并发性和内存故事(正在变得越来越好), 并且与gems的兼容性最广(某些部分用C编写)。总而言之, MRI是通用Ruby代码的可靠可靠选择。

对于大型的企业部署, 或者需要与Java代码(或其他JVM语言)进行交互或需要高度发展的并发模式的情况, JRuby是一个引人注目的选择。

当然, 如果你有独特的需求(例如, 编写JavaScript, 在当前的嵌入式设备上运行等), 那么其他Ruby替代品可能正是你所需要的。

Ruby拥有各种各样的Ruby运行时和解释器供你选择, 显示出自己是一种灵活的语言, 可用于各种计算环境, 从大型企业Java部署车间到控制办公室交通信号灯的软件你将Raspberry Pi吸引到上周末。是的, 选择正确的工具以达到正确的目的是必不可少的, 但是希望本文向你展示了Ruby远远超过了操作系统随附的默认Ruby解释器。

提议对语言进行更改时, 其他Ruby实现团队与核心Ruby MRI团队一起工作极大地增强了Ruby的世界。他们为Ruby实现社区增加了多样性, 增加了他们来之不易的Ruby实现经验以及他们对语言功能的看法。 Ruby发烧友集体欠这些团队很多谢意。感谢他们的努力!

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?