运行符合旧版Ruby语言版本的遗留代码块

时间:2014-11-11 14:58:28

标签: ruby jruby rubymine

我不知道该怎么称呼这个问题,所以如果你不想改变它,请成为我的客人。

我想知道是否有某种方法可以运行一个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,然后根据该测试的结果执行代码,但这不符合我的需求,最好只重新因为我们所有的单元测试和验收测试都归结于此。

3 个答案:

答案 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,那么你就获得了速度。