到目前为止,我一直在用POSIX shell编写我所有的脚本,这样我就可以在我使用的所有机器(macOS,各种Linux,FreeBSD(上运行它们。我喜欢有一个统一的体验,我可以从 git 中提取我的点文件,并准备好我所有的设置和脚本。
然而,POSIX shell是一种非常令人恼火的语言,我一直在考虑切换到Ruby来满足我的脚本需求。不幸的是,在我开始之前,我意识到macOS附带了Ruby 2.3.7,而我经常需要使用的一台机器只有Ruby 1.8.7。这是一台我没有 sudo 访问权限的学校机器,所以我无法安装更高版本的 Ruby。
TL;博士
是否可以编写可以在 1.8.7 和 2.3.7 上运行的 Ruby 脚本(希望介于两者之间的所有内容(?是否有一套我可以遵循的准则来帮助我避免不兼容的语言功能?
是的,这是可能的,只要您将自己限制在 Ruby 1.8.7、Ruby 2.3.7 的语言和库特性以及介于两者之间的所有功能。
向后兼容性的最后一个重大突破是从Ruby 1.8跳到Ruby 1.9。字符串处理完全改变了,所以任何与文本处理有关的事情,都需要非常小心。
我的头顶:
- 在 Ruby 1.8 中,字符串被认为是一个字节序列。在 Ruby 1.9 中。字符串是不同迭代器的工厂,根据代码点、字符或字节进行迭代。
- 因此,在 Ruby 1.9 中,字符串不再
Enumerable
。 - 索引到字符串中将返回 Ruby 1.8 中的
Integer
和 Ruby 1.9 中的单字符String
。 - 字符文本(例如
?a
( 将在 Ruby 1.8 中计算出Integer
,在 Ruby 1.9 中计算为单字符String
。 - 在 Ruby 1.8 中,假定所有字符串都使用相同的编码(通常是 ASCII,但可以更改为非常有限的集合,即 UTF-8 和几个亚洲编码(。Ruby 1.9 是完全编码感知的,每个字符串都有自己单独的编码,每个 I/O 流有两个编码(一个内部编码和一个外部编码(,每个源文件都有一个单独的编码。
最好的办法可能是限制自己只使用 ISO Ruby 语言规范中指定的内容。该规范是专门编写的,以便当时所有现有的Ruby实现(MRI,YARV,IronRuby,JRuby,MacRuby,Rubinius(将自动兼容,这基本上意味着该规范仅指定Ruby 1.8.6,Ruby 1.8.7和Ruby 1.9.0交集的最小必需子集。
由于从那时起没有任何向后不兼容的更改,因此您可以放心,您的代码将适用于从Ruby 1.8.6到(但不包括(3.0的所有版本,以及所有符合ISO标准的Ruby实现,据我所知,这些实现是MRI,YARV,JRuby,IronRuby,Rubinius,MacRuby,MRuby,MagLev和TruffleRuby。