Help us understand the problem. What is going on with this article?

rubylang/all-ruby で ruby の全リリースの挙動を確かめる

More than 1 year has passed since last update.

Ruby Advent Calendar 2018 の 6 日目の記事です。
同じ内容で blog にも投稿 しています。

docker hub に rubylang/all-ruby というイメージがあって、 ruby の全リリースバージョンの挙動を確かめることができます。

ダウンロード

docker をインストールして使えるようにした後、普通に docker pull rubylang/all-ruby であらかじめダウンロードするか、初回実行時の自動ダウンロードに任せるかします。

Tags だと 3 GB と書いてありますが、手元のイメージを確認してみたところ、 10.2GB もあったので、ネットワークがしっかりしているところでダウンロードする方が良いでしょう。

% docker images | grep rubylang/all-ruby
rubylang/all-ruby                          latest              d6f0f07f0df6        4 weeks ago         10.3GB

実行例

./all-ruby コマンドで全てのリリースバージョンで実行して、実行結果が同じものはまとめて出力されます。

% docker run -it --rm rubylang/all-ruby ./all-ruby -e 'print("hello\n")'
ruby-0.49             hello
...
ruby-2.6.0-preview2   hello

出力が違う場合は別々に出てきますが、 pid などの違いはまとめられます。

% docker run -it --rm rubylang/all-ruby ./all-ruby -e 'p "hello"'
ruby-0.49             -e:1: syntax error
                  #<Process::Status: pid 7 exit 1>
ruby-0.50             -e:1: syntax error
                  #<Process::Status: pid 8 exit 1>
ruby-0.51             -e:1: undefined method `p' for "main"(Object)
                  #<Process::Status: pid 9 exit 1>
ruby-0.54             -e:1:in method `p': undefined method `p' for "main"(Object)
                  #<Process::Status: pid 10 exit 1>
ruby-0.55             -e:1: undefined method `p' for "main"(Object)
                  #<Process::Status: pid 11 exit 1>
...
ruby-0.76             -e:1: undefined method `p' for "main"(Object)
                  #<Process::Status: pid 20 exit 1>
ruby-0.95             -e:1: undefined method `p' for main(Object)
                  #<Process::Status: pid 21 exit 1>
ruby-0.99.4-961224    "hello"
...
ruby-2.6.0-preview2   "hello"

バージョンによる違いの例

Time#to_s

何度か書式が変わっていることがわかります。

% docker run -it --rm rubylang/all-ruby ./all-ruby -e 'print(Time.at(0))'
ruby-0.49             Thu Jan 01 00:00:00 UTC 1970
...
ruby-1.8.5-preview2   Thu Jan 01 00:00:00 UTC 1970
ruby-1.8.5-preview3   Thu Jan 01 00:00:00 +0000 1970
...
ruby-1.8.5-p231       Thu Jan 01 00:00:00 +0000 1970
ruby-1.8.6-preview1   Thu, Jan 01 1970 00:00:00 +0000
...
ruby-1.8.6-preview3   Thu, Jan 01 1970 00:00:00 +0000
ruby-1.8.6            Thu Jan 01 00:00:00 +0000 1970
...
ruby-1.8.7-p374       Thu Jan 01 00:00:00 +0000 1970
ruby-1.9.0-0          1970-01-01 00:00:00 +0000
...
ruby-2.6.0-preview2   1970-01-01 00:00:00 +0000

Array#filter

2.6 で追加されたメソッドが Array#filterがなかった をみて昔あったということを気づけたので確認してみたところ、 1.6 までの挙動と違う挙動で 2.6 に追加されていることがわかりました。

% docker run -it --rm rubylang/all-ruby ./all-ruby -e 'a=[1,2]; p a.filter{|x|x+1}'
(略)
ruby-1.1b7            [2, 3]
...
ruby-1.4.6            [2, 3]
ruby-1.6.0            -e:1: warning: Array#filter is deprecated; use Array#collect!
                      [2, 3]
...
ruby-1.6.8            -e:1: warning: Array#filter is deprecated; use Array#collect!
                      [2, 3]
ruby-1.8.0            -e:1: undefined method `filter' for [1, 2]:Array (NoMethodError)
                  #<Process::Status: pid 142 exit 1>
...
ruby-1.8.7-p374       -e:1: undefined method `filter' for [1, 2]:Array (NoMethodError)
                  #<Process::Status: pid 216 exit 1>
ruby-1.9.0-0          -e:1:in `<main>': undefined method `filter' for [1, 2]:Array (NoMethodError)
                  #<Process::Status: pid 217 exit 1>
...
ruby-2.6.0-preview1   -e:1:in `<main>': undefined method `filter' for [1, 2]:Array (NoMethodError)
                  #<Process::Status: pid 459 exit 1>
ruby-2.6.0-preview2   [1, 2]

nil の object_id

最初は 0 だったのがだんだん大きくなっていったようです。

% docker run -it --rm rubylang/all-ruby ./all-ruby -e 'print(nil.id)'
ruby-0.49             0
...
ruby-0.95             0
ruby-0.99.4-961224    2
...
ruby-1.1a5            2
ruby-1.1a6            4
...
ruby-1.8.2-preview3   4
ruby-1.8.2-preview4   -e:1: warning: Object#id will be deprecated; use Object#object_id
                      4
...
ruby-1.8.7-p374       -e:1: warning: Object#id will be deprecated; use Object#object_id
                      4
ruby-1.9.0-0          -e:1:in `<main>': undefined method `id' for nil:NilClass (NoMethodError)
                  #<Process::Status: pid 217 exit 1>
...
ruby-2.6.0-preview2   -e:1:in `<main>': undefined method `id' for nil:NilClass (NoMethodError)
                  #<Process::Status: pid 461 exit 1>
% docker run -it --rm rubylang/all-ruby ./all-ruby -e 'print(nil.object_id)'
(略)
ruby-1.6.8            -e:1: undefined method `object_id' for nil (NameError)
                  #<Process::Status: pid 142 exit 1>
ruby-1.8.0            4
...
ruby-1.9.3-p551       4
ruby-2.0.0-preview1   8
...
ruby-2.6.0-preview2   8

その他

docker run -it --rm rubylang/all-ruby /bin/bash で中に入って色々と調べることができます。

ヘルプ

引数なしで ./all-ruby を実行すると usage がでてきます。

% docker run -it --rm rubylang/all-ruby ./all-ruby
usage: all-ruby RUBY-ARGS
environment variables:
  ALL_RUBY_SINCE=ruby-1.4
  ALL_RUBY_SHOW_DUP=yes
  ALL_RUBY_BINS='ruby-2.1.10 ruby-2.2.10 ruby-2.3.7 ruby-2.4.4 ruby-2.5.1'
  ALL_RUBY_ADDBINS=./ruby       space-separated binaries to be run

docker run -it --rm rubylang/all-ruby -h のようなオプション指定は、その引数で ruby を実行するという意味になるので、 all-ruby 自体のオプションとしては扱わないようです。

環境変数指定

env コマンドを使って環境変数を設定して all-ruby を実行すると、例えば ruby 1.4.0 以降のみで実行などができるようです。

% docker run -it --rm rubylang/all-ruby env ALL_RUBY_SINCE=ruby-1.4 ./all-ruby -e 'p "hello"'
ruby-1.4.0            "hello"
...
ruby-2.6.0-preview2   "hello"

まとめ

複数の ruby のリリースバージョンの動作をまとめて確認できる docker イメージの rubylang/all-ruby を紹介しました。
サイズが大きいのでディスクに余裕のある環境だけに入れて、常用できるようにしておくと歴史的な調査などに便利です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away