2022/07/14 今回の気になった bugs.ruby のチケット

今週は :"@=".inspect の結果が Ruby で評価できない文字列を返すというバグ報告がありました。

[Bug #18905] :"@=".inspect is non-evaluatable

  • :"@=".inspect の結果が Ruby で評価できない文字列を返すというバグ報告
# :@= を返すが
p :"@=".inspect # => ":@="

# :@= という Symbol をリテラルで定義できない
# :@= のような Symbol を定義する場合は "" でくくる必要がある
# error: `@' without identifiers is not allowed as an instance variable name
:@=
  • これは以下の条件の時に再現する
    • @ @@ $ [ から始まり
    • prefix の後に識別子が続かず
    • = で終了する
# こういう Symbol は "" がつく
p :"42hoge"   # => :"42hoge"
p :"+aa"      # => :"+aa"
p :"@+"       # => :"@+"

# 以下は "" がつかない
p :"@="       # => :@=
p :"@hoge="   # => :@hoge=
p :"[][]="    # => :[][]=
p :"$$$$="    # => :$$$$=
  • 前提として #inspect は評価できる Ruby のコードを返すわけではない
# 必ずしもこういう式が成り立つわけではない
eval(obj.inspect)
  • これは ruby-2.2.0-preview2 のタイミングで挙動が変わったらしい
$ docker run --rm -e "ALL_RUBY_SINCE=ruby-2.0" rubylang/all-ruby ./all-ruby -e "puts '4_to_5='.to_sym.inspect"
ruby-2.0.0-p0       :"4_to_5="
...
ruby-2.2.0-preview1 :"4_to_5="
ruby-2.2.0-preview2 :4_to_5=
...
ruby-3.2.0-preview1 :4_to_5=

[Feature #18913] Add object name to the NoMethodError error message: undefined method _method_' forclass' in `object_name'

  • エラーメッセージにオブジェクト名を追加したいという提案
  • 例えば以下のようなエラーメッセージに対して
bar = nil
bar.i_wish_i_saw_the_name_bar
# (irb):00:in `<main>': undefined method `i_wish_i_saw_the_name_bar' for nil:NilClass (NoMethodError)
  • 以下のように bar というレシーバの名前を出したいという提案
bar = nil
bar.i_wish_i_saw_the_name_bar
#(irb):00:in `<main>': undefined method `i_wish_i_saw_the_name_bar' for nil:NilClass in `bar' (NoMethodError)
#                                                                                        ^^^ It should mention the object name
  • 例えば以下のようなケースで役に立つ
    • どの foo 呼び出しでエラーになっているのかがわからない
a = OpenStruct.new
b = nil
c = nil
who_failed = a.foo & b.foo & c.foo
# (irb):00:in `<main>': undefined method `foo' for nil:NilClass (NoMethodError)
$ ruby test.rb
test.rb:5:in `<main>': undefined method `foo' for nil:NilClass (NoMethodError)

who_failed = a.foo & b.foo & c.foo
                      ^^^^

$ ruby -v
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]