1. znz

    Posted

    znz
Changes in title
+rubylang/all-ruby で ruby の全リリースの挙動を確かめる
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,173 @@
+docker hub に [rubylang/all-ruby](https://hub.docker.com/r/rubylang/all-ruby/) というイメージがあって、 ruby の全リリースバージョンの挙動を確かめることができます。
+
+## ダウンロード
+
+docker をインストールして使えるようにした後、普通に `docker pull rubylang/all-ruby` であらかじめダウンロードするか、初回実行時の自動ダウンロードに任せるかします。
+
+[Tags](https://hub.docker.com/r/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がなかった](https://qiita.com/ikemo/items/384ed779f11f9fb9a582#arrayfilter%E3%81%8C%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F) をみて昔あったということを気づけたので確認してみたところ、 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` を紹介しました。
+サイズが大きいのでディスクに余裕のある環境だけに入れて、常用できるようにしておくと歴史的な調査などに便利です。