我不知道该怎么称呼这个问题,所以如果你不想改变它,请成为我的客人。
我想知道是否有某种方法可以运行一个Ruby代码块,以符合ruby语言的普遍版本。它本质上是某种“兼容模式”,但仅适用于一段代码。
我的想法是查看RUBY_VERSION全局变量,看看Ruby是否表现得像那个版本那样,但这似乎什么都不做。这是我的尝试:
puts RUBY_VERSION
an_object = Time.now
an_object.tap do |o|
puts 'in tep function'
end # ===> an_object
RUBY_VERSION = 1.7 #potentially change ruby version to an older version to run legacy code
#attempt to run a function that was not available in version 1.7, (just an example)
an_object.tap do |o|
puts 'in tep function'
end # ===> an_object
puts RUBY_VERSION
我意识到我可以对条件进行编码,并测试当前版本的Ruby,然后根据该测试的结果执行代码,但这不符合我的需求,最好只重新因为我们所有的单元测试和验收测试都归结于此。
答案 0 :(得分:0)
如果您的系统上安装了多个红宝石,例如rbenv
:
ls -l ~/.rbenv/versions/
drwxr-xr-x 5 jared staff 170 Nov 7 13:59 1.8.7-p374
drwxr-xr-x 6 jared staff 204 Oct 31 15:02 2.1.1
drwxr-xr-x 6 jared staff 204 Oct 30 12:19 2.1.2
drwxr-xr-x 6 jared staff 204 Oct 30 12:03 2.1.4
..然后你可以从更新的红宝石“淘汰”到旧的红宝石。我建议使用Open3.popen3,但有更简单的方法,例如Kernel#system。
$ ruby --version
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]
$ irb
irb(main):002:0> ruby = "/Users/jared/.rbenv/versions/1.8.7-p374/bin/ruby"
irb(main):016:0> Open3.popen3(ruby) { |stdin, stdout, stderr, wait_thr|
irb(main):017:1* stdin.puts "puts RUBY_VERSION"
irb(main):018:1> stdin.close
irb(main):019:1> puts stdout.read
irb(main):020:1> }
1.8.7
=> nil
如何将“旧红宝石”代码作为字符串保留给读者。也许试试Method#source_location?
另一个挑战是如何从“旧红宝石”中返回对象。使用YAML进行序列化是一种选择。
然而,我同意@ p11y“对此唯一可持续的解决方案是将代码移植到更新的Ruby”。
答案 1 :(得分:0)
Ruby的大多数实现仅支持该语言的单个版本。例如,YARV 2.1.4仅支持Ruby 2.1.4,MRI 1.8.7仅支持Ruby 1.8.7,依此类推。
JRuby,IronRuby和Rubinius曾经一次或多次支持多个版本的Ruby(这是从Ruby 1.8到Ruby 1.9的过渡时期),但是大多数版本已经删除了这个功能。
即便如此,他们每个解释器实例只支持一个版本。
答案 2 :(得分:0)
backports宝石可能就是您正在寻找的东西。来自自述文件:
' backports'是为了更容易编写跨不同版本的Ruby运行的ruby代码。
例如,如果你想使用flat_map,即使在不包含它的Ruby实现中,以及新的bsearch方法:
require 'backports/1.9.2/enumerable/flat_map'
require 'backports/2.0.0/array/bsearch'
这将启用Enumerable#flat_map和Array#bsearch,使用本机版本(如果可用)或以其他方式提供纯Ruby版本。
此外,您可以随时向Ruby对象询问它知道如何操作,方法是扫描其methods
列表,或使用respond_to?
。如果它不知道如何做某事,那么你可以提供一个等效的方法。您的等效项可能是纯Ruby解决方案,运行速度较慢,但可以完成工作,至少可以保持功能。如果你以后运行一个具有已编译代码的更新的Ruby,那么你就获得了速度。