16
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

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

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 を紹介しました。
サイズが大きいのでディスクに余裕のある環境だけに入れて、常用できるようにしておくと歴史的な調査などに便利です。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
16
Help us understand the problem. What are the problem?