2021/05/20 今週の気になった bugs.ruby のチケット

今週は Psych の非互換な変更に対するチケットできていました。
かなり影響範囲が広いのでどうなるか今後どうなっていくのか気になる。

[Bug #17866] Incompatible changes with Psych 4.0.0

require "psych"

def process thing
  thing.each do |item|
    case item
    when Array
      process item
    when Hash
      # ...
    when String
      # ...
    end
  end
end

user_input = <<~EOS
--- &1
- *1
EOS

# error: stack level too deep (SystemStackError)
process Psych.load(user_input)
# :text: という書き方が許可されてほしいが許可されていない
require "psych"
require "tempfile"
require "yaml"

Tempfile.open "example" do |file|
  file.write %(:text: "Hello.")
  file.rewind
  # load は OK
  puts "YAML Contents: #{YAML.load file}"
  # load_file は NG
  puts "YAML Contents: #{YAML.load_file file}"
end
  • かなり影響範囲が大きそうなので Psych のリリースは様子を見たほうがよかったんじゃないのかなあ、と思う一方でリリースしないとこういう問題はわからないので難しいところ

[PR 4414] Fix some typos by spell checker

$ cat test.txt
currrent
# スペルミスがある位置を出力してくれる
$ codespell test.txt
test.txt:1: currrent ==> current
# -w を付けると修正してくれる
$ codespell test.txt -w
FIXED: test.txt
$ cat test.txt
current
  • 普通に便利そう

[Feature #11747] "bury" feature, similar to 'dig' but opposite

  • 少し前のチケット
  • Hash#dig のように複数のキーを渡してネストしてデータ構造を生成できるようにする Hash#bury というメソッドの提案
data = { users: [{ name: "homu" }] }

# data[:users][0][:name] を以下のようにしてアクセスできる
pp data.dig(:users, 0, :name)
# => "homu"

# dig のようにネストしたデータ構造を1回で代入する
data.bury(:users, 0, :name, 'mami')
  • ただし、空のデータに対してネストした構造を定義する場合にどのクラスで定義すべきなのか、という課題がある
# こう定義した時にどうなってほしい?
# struct なども考慮する必要がある
{}.bury(0, 1, 2, :foo)
# => {0 => {1 => {2 => :foo}}}
# or
# => [[nil, [nil, nil, :foo]]]
# これでネストしたデータを定義できるがうーん
root = {}
[:a, :b, :c].reduce(root) { _1[_2] ||= {} }[:d] = 'E'
pp root
# => {:a=>{:b=>{:c=>{:d=>"E"}}}}