---
title: Ruby 3.1 で非互換になる YAML.load
tags: 
author: [osyo](https://convert.docswell.com/user/pink_bangbi)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/NPEXQ4M1JX.jpg?width=480
description: https://omotesandorb.connpass.com/event/235092/
published: January 06, 22
canonical: https://convert.docswell.com/s/pink_bangbi/K67RV5-2022-01-06-201330
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/NPEXQ4M1JX.jpg)

Ruby 3.1 で非互換になる
YAML.load
Omotesando.rb #70


# Page. 2

![Page Image](https://bcdn.docswell.com/page/63EK9ZGMED.jpg)

自己紹介
名前：osyo
Twitter : @pink_bangbi
github : osyo-manga
ブログ : Secret Garden(Instrumental)
Rails エンジニア
好きな Ruby の機能は Refinements
Ruby 3.1 で気になる機能は Hash のショートハンドと debug.gem
RubyKaigi Takeout 2021
Use Macro all the time ~ マクロを使いまくろ ~
Advent Calendar やってるよ！
Ruby の TracePoint を使ってメソッド呼び出しをトレースしよう
一人 bugs.ruby Advent Calendar


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4L73WDN275.jpg)

Ruby 3.1 で非互換になる YAML.load


# Page. 4

![Page Image](https://bcdn.docswell.com/page/V87DKPW6JG.jpg)

概要


# Page. 5

![Page Image](https://bcdn.docswell.com/page/4VJPKNXZE8.jpg)

概要
YAML は psych というライブラリで実装されている
`YAML # =&gt; Psych`
`YAML.load`
は実質 `Psych.load` にあたる


# Page. 6

![Page Image](https://bcdn.docswell.com/page/L2EVVKLMEQ.jpg)

概要
YAML は psych というライブラリで実装されている
`YAML # =&gt; Psych`
`YAML.load`
は実質 `Psych.load` にあたる
この psych が 4.0.0 で非互換になった
`Psych.load`
周りが非互換になった


# Page. 7

![Page Image](https://bcdn.docswell.com/page/Z57GLQXXEL.jpg)

概要
YAML は psych というライブラリで実装されている
`YAML # =&gt; Psych`
`YAML.load`
は実質 `Psych.load` にあたる
この psych が 4.0.0 で非互換になった
`Psych.load`
周りが非互換になった
Ruby 3.1 ではこの psych 4.0.0 がバンドルされている


# Page. 8

![Page Image](https://bcdn.docswell.com/page/V4EQYK85JP.jpg)

psych 4.0.0 の非互換な変更


# Page. 9

![Page Image](https://bcdn.docswell.com/page/DKJ4WP2V71.jpg)

その前に


# Page. 10

![Page Image](https://bcdn.docswell.com/page/PLE1Y9M47G.jpg)

Psych.safe_load について


# Page. 11

![Page Image](https://bcdn.docswell.com/page/8GEWGQ3ZJ2.jpg)

Psych.safe_load について
`Psych.load`
ソッドがある
とは別に安全に YAML ファイルを読み込む `Psych.safe_load` というメ


# Page. 12

![Page Image](https://bcdn.docswell.com/page/W47ZLWVLJ3.jpg)

Psych.safe_load について
`Psych.load`
ソッドがある
とは別に安全に YAML ファイルを読み込む `Psych.safe_load` というメ
と比較して再帰的な特定のクラスのオブジェクトしか変換しなかったり、
データ構造はデフォルトでは許可されていなかったりする
`Psych.load`


# Page. 13

![Page Image](https://bcdn.docswell.com/page/KYJ6WG5MJV.jpg)

Psych.safe_load について
`Psych.load`
ソッドがある
とは別に安全に YAML ファイルを読み込む `Psych.safe_load` というメ
と比較して再帰的な特定のクラスのオブジェクトしか変換しなかったり、
データ構造はデフォルトでは許可されていなかったりする
`Psych.load_file` と対になる `Psych.safe_load_file` メソッドも存在している
`Psych.load`


# Page. 14

![Page Image](https://bcdn.docswell.com/page/5GJ5MVYQJ4.jpg)

デフォルトでは以下のクラスのオブジェクトしか変換されない
`TrueClass` `FalseClass` `NilClass` `Numeric` `String` `Array` `Hash`


# Page. 15

![Page Image](https://bcdn.docswell.com/page/V9E293GW7R.jpg)

デフォルトでは以下のクラスのオブジェクトしか変換されない
`TrueClass` `FalseClass` `NilClass` `Numeric` `String` `Array` `Hash`
`Psych.safe_load`
だと `Date` オブジェクトは変換されない
1
2
3
4
require &quot;psych&quot;
require &quot;date&quot;
5
6
7
8
pp Psych.safe_load(&quot;name: homu&quot;)
# =&gt; {&quot;name&quot;=&gt;&quot;homu&quot;}
9
10
# OK: String
# NG: Date
は問題ない
オブジェクトは変換できずにエラーになる
# error: `find&#039;: Tried to load unspecified class: Date (Psych::DisallowedClass)
pp Psych.safe_load(&quot;date: 2020-01-01&quot;)


# Page. 16

![Page Image](https://bcdn.docswell.com/page/5D7Y41V9EM.jpg)

デフォルトでは再帰的なデータ構造はデフォルトで許可されてない


# Page. 17

![Page Image](https://bcdn.docswell.com/page/2VENY2MDJ8.jpg)

デフォルトでは再帰的なデータ構造はデフォルトで許可されてない
`&amp;default` のようなエイリアスがあるとエラーになる
1
2
3
require &quot;psych&quot;
4
5
6
default: &amp;default
aaa: aaa
bbb: bbb
data = &lt;&lt;~EOS
7
8
9
10
11
development:
&lt;&lt;: *default
test:
&lt;&lt;: *default
production:
12
13
14
15
16
17
&lt;&lt;: *default
EOS
読み込めない
# NG:
# error: Unknown alias: default (Psych::BadAlias)
pp Psych.safe_load(data)


# Page. 18

![Page Image](https://bcdn.docswell.com/page/GY79P1N8E3.jpg)

これらは引数で制御する事ができる
`Date` などを許可する場合は


# Page. 19

![Page Image](https://bcdn.docswell.com/page/5G78D4KZ7D.jpg)

これらは引数で制御する事ができる
`Date` などを許可する場合は
`permitted_classes:` に許可するクラスのオブジェクトの配列を渡す
1
require &quot;psych&quot;
2
3
4
5
6
require &quot;date&quot;
# OK
pp Psych.safe_load(&quot;date: 2020-01-01&quot;, permitted_classes: [Date])
# =&gt; {&quot;date&quot;=&gt;#&lt;Date: 2020-01-01 ((2458850j,0s,0n),+0s,2299161j)&gt;}


# Page. 20

![Page Image](https://bcdn.docswell.com/page/ML7LM6Z1JR.jpg)

再帰的なデータ構造を許可する場合は


# Page. 21

![Page Image](https://bcdn.docswell.com/page/54EMY5V5EW.jpg)

再帰的なデータ構造を許可する場合は
`aliases: true` を渡す
1
2
3
require &quot;psych&quot;
4
5
6
default: &amp;default
aaa: aaa
development:
data = &lt;&lt;~EOS
7
8
9
10
11
&lt;&lt;: *default
EOS
12
# =&gt; {&quot;default&quot;=&gt;{&quot;aaa&quot;=&gt;&quot;aaa&quot;}, &quot;development&quot;=&gt;{&quot;aaa&quot;=&gt;&quot;aaa&quot;}}
# OK
pp Psych.load(data, aliases: true)


# Page. 22

![Page Image](https://bcdn.docswell.com/page/ZPER932ZJ9.jpg)

psych 4.0.0 だと
`Psych.load` -&gt; `Psych.safe_load`
`Psych.load_file` -&gt;
`Psych.safe_load_file`
に置き換わった


# Page. 23

![Page Image](https://bcdn.docswell.com/page/NP7XQ4D1EX.jpg)

Ruby 3.1 では
psych 4.0.0 がバンドルされる


# Page. 24

![Page Image](https://bcdn.docswell.com/page/637K9ZXM7D.jpg)

なので今まで読み込めていた
YAML ファイルが読み込めなくなる
可能性がある


# Page. 25

![Page Image](https://bcdn.docswell.com/page/4LJ3WD52J5.jpg)

もう1つの非互換な変更


# Page. 26

![Page Image](https://bcdn.docswell.com/page/V8JDKPD6EG.jpg)

引数のシグネチャが変わった
psych 4.0.0 以前はオプション引数とキーワード引数の2つ受け取るようになっていた
1
2
3
def self.safe_load(
yaml,
legacy_permitted_classes = NOT_GIVEN,
4
5
6
7
legacy_permitted_symbols = NOT_GIVEN,
legacy_aliases = NOT_GIVEN,
legacy_filename = NOT_GIVEN,
permitted_classes: [],
8
9
10
11
permitted_symbols: [],
aliases: false,
filename: nil,
fallback: nil,
12
13
14
15
symbolize_names: false,
freeze: false)
# ...
end


# Page. 27

![Page Image](https://bcdn.docswell.com/page/4VEPKN6Z78.jpg)

オプション引数とキーワード引数を両方渡せる
1
2
3
require &quot;psych&quot;
require &quot;date&quot;
4
5
6
7
8
pp Psych::VERSION
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# =&gt; &quot;3.2.0&quot;
data = &lt;&lt;~EOS
default: &amp;default
aaa: 2020-01-1
development:
&lt;&lt;: *default
EOS
オプション引数を受け取る
#
pp Psych.safe_load(data, [Date], [], true)
キーワード引数でも受け取れる
#
pp Psych.safe_load(data, permitted_classes: [Date], aliases: true)
両方渡した場合はオプション引数が優先される
#
# no error
pp Psych.safe_load(&quot;2020-01-1&quot;, [Date], permitted_classes: [])
# error: Tried to load unspecified class: Date (Psych::DisallowedClass)
pp Psych.safe_load(&quot;2020-01-1&quot;, [], permitted_classes: [Date])


# Page. 28

![Page Image](https://bcdn.docswell.com/page/L27VVK3M7Q.jpg)

psych 4.0.0 以降はキーワード引数のみを受け取る
1
2
3
4
5
6
7
8
9
10
def self.load(
yaml,
permitted_classes: [Symbol],
permitted_symbols: [],
aliases: false, filename: nil,
fallback: nil,
symbolize_names: false,
freeze: false)
# ...
end


# Page. 29

![Page Image](https://bcdn.docswell.com/page/Z5JGLQ3X7L.jpg)

キーワード引数だけ渡せる
1
2
3
require &quot;psych&quot;
require &quot;date&quot;
4
5
6
7
8
pp Psych::VERSION
9
10
11
12
13
14
15
16
17
18
# =&gt; &quot;3.2.0&quot;
data = &lt;&lt;~EOS
default: &amp;default
aaa: 2020-01-1
development:
&lt;&lt;: *default
EOS
キーワード引数でも受け取れる
#
pp Psych.safe_load(data, permitted_classes: [Date], aliases: true)
エラー
#
pp Psych.safe_load(data, [Date], [], true)


# Page. 30

![Page Image](https://bcdn.docswell.com/page/V47QYK55EP.jpg)



# Page. 31

![Page Image](https://bcdn.docswell.com/page/DKE4WP9VJ1.jpg)

psych 4.0.0 への対応策


# Page. 32

![Page Image](https://bcdn.docswell.com/page/PL71Y9K4JG.jpg)

引数の値で制御する
必要に応じてキーワード引数で制御を行う
1
2
3
require &quot;psych&quot;
require &quot;date&quot;
4
5
6
7
data = &lt;&lt;~EOS
default: &amp;default
aaa: 2020-01-1
development:
8
9
10
11
&lt;&lt;: *default
EOS
12
13
14
pp Psych.load(data, permitted_classes: [Date], aliases: true)
# =&gt; {&quot;default&quot;=&gt;{&quot;aaa&quot;=&gt;#&lt;Date: 2020-01-01 ((2458850j,0s,0n),+0s,2299161j)&gt;},
#
&quot;development&quot;=&gt;{&quot;aaa&quot;=&gt;#&lt;Date: 2020-01-01 ((2458850j,0s,0n),+0s,2299161j)&gt;}}
# OK


# Page. 33

![Page Image](https://bcdn.docswell.com/page/8G7WGQDZE2.jpg)

バージョンを固定する
Gemfile にバージョンを指定する
gem 内で `Psych.load` が使われている場合などはこの対処になりそう
1
2
gem &quot;psych&quot;, &quot;&lt; 4.0.0&quot;
3
4
#
4.0.0
# gem &quot;psych&quot;, &quot;&gt;= 4.0.0&quot;
逆に
以上を使用したい場合はこんな感じ


# Page. 34

![Page Image](https://bcdn.docswell.com/page/W4JZLWGLE3.jpg)

Psych.unsafe_load を使う
の変わりに `Psych.unsafe_load` を使う
`Psych.unsafe_load` は以前の `Psych.load` と同じ挙動になる
`Psych.load`
1
2
3
4
require &quot;psych&quot;
require &quot;date&quot;
5
6
7
8
default: &amp;default
aaa: 2020-01-1
development:
&lt;&lt;: *default
9
10
11
12
13
14
data = &lt;&lt;~EOS
EOS
# OK
pp Psych.unsafe_load(data)
# =&gt; {&quot;default&quot;=&gt;{&quot;aaa&quot;=&gt;#&lt;Date: 2020-01-01 ((2458850j,0s,0n),+0s,2299161j)&gt;},
#
&quot;development&quot;=&gt;{&quot;aaa&quot;=&gt;#&lt;Date: 2020-01-01 ((2458850j,0s,0n),+0s,2299161j)&gt;}}


# Page. 35

![Page Image](https://bcdn.docswell.com/page/KYE6WGYMEV.jpg)

まとめ


# Page. 36

![Page Image](https://bcdn.docswell.com/page/5GE5MVGQE4.jpg)

まとめ


# Page. 37

![Page Image](https://bcdn.docswell.com/page/V97293YWJR.jpg)

まとめ
YAML は psych というライブラリで実装されている
`YAML == Psych``


# Page. 38

![Page Image](https://bcdn.docswell.com/page/5DJY41G97M.jpg)

まとめ
YAML は psych というライブラリで実装されている
`YAML == Psych``
psych 4.0.0 から `Psych.safe_load` が `Psych.load` に置き換わるので結果的に非互換
になる
更にキーワード引数のみ受け付けるようになる


# Page. 39

![Page Image](https://bcdn.docswell.com/page/2V7NY2GDE8.jpg)

まとめ
YAML は psych というライブラリで実装されている
`YAML == Psych``
psych 4.0.0 から `Psych.safe_load` が `Psych.load` に置き換わるので結果的に非互換
になる
更にキーワード引数のみ受け付けるようになる
Ruby 3.1 では psych 4.0.0 がデフォルトでバンドルされるので注意


# Page. 40

![Page Image](https://bcdn.docswell.com/page/GYJ9P1W873.jpg)

まとめ
YAML は psych というライブラリで実装されている
`YAML == Psych``
psych 4.0.0 から `Psych.safe_load` が `Psych.load` に置き換わるので結果的に非互換
になる
更にキーワード引数のみ受け付けるようになる
Ruby 3.1 では psych 4.0.0 がデフォルトでバンドルされるので注意
psych 4.0.0 を使う場合は Ruby 3.1 未満でも影響がある


# Page. 41

![Page Image](https://bcdn.docswell.com/page/5GJ8D4NZJD.jpg)

参照
Ruby の Psych.safe_load（YAML.safe_load）の引数が Psych v4.0.0 から非互換になる Secret Garden(Instrumental)
Ruby の YAML.load が非互換になる（かもしれない） - Secret Garden(Instrumental)


