今週の気になった bugs.ruby

1週間だとあんまりたまらないかと思ったんですが思ったよりもたまりました。
内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。

Feature #16378 Support leading arguments together with ...

def method_missing(name, ...)
  if name.to_s.end_with?('?')
    self[name]
  else
    fallback(name, ...)
  end
end

Bug #16948 hash.each(&method(:something)) behavior changed without warning on master

  • ruby 2.8.0dev で hash.each(&method(:something) が動かなくなったというバグ報告
    • 2.7.1 では問題ない
def foo(a, b)
  p [a, b]
end

# error: in `foo': wrong number of arguments (given 1, expected 2) (ArgumentError)
{1 => 2}.each(&method(:foo))
def foo(a, b)
  p [a, b]
end

def bar(a, b = 2)
  p [a, b]
end

foo_lambda = method(:foo).to_proc
bar_lambda = method(:bar).to_proc

{a: 1}.each(&foo_lambda)   # => [:a, 1]
{a: 1}.each(&bar_lambda)   # => [[:a, 1], 2]

Bug #16947 private method unexpected behavior

Feature #16946 Add an intersperse method

  • 要素間に任意の値を挿入するメソッドの提案
[1, 2, 3].intersperse(0)
#=> [1, 0, 2, 0, 3]

'Hello'.intersperse('-')
#=> "H-e-l-l-o"
  • どういうケースで利用できるんだろうか
  • 既存のメソッドだと以下のような感じらしい
[1, 2, 3].flat_map { |i| [i, 0] }[0...-1]
#=> [1, 0, 2, 0, 3]

'Hello'.gsub(/(?<=.)./, '-\0')
#=> "H-e-l-l-o"

'Hello'.chars.join('-')
#=> "H-e-l-l-o"

Feature #16939 Alias _1 as _ for block numbered params

  • __1エイリアスにする提案
  • _ のほうが短いけど意味がわかりづらいかも…?
  • 確か _ は『参照しない引数』みたいな意味で使われている事が多いみたいな話があった気がする
# 第二引数は参照しないので _ を使う
hash.map { |k, _| k.to_s }
  • _ は既存のコードで多く利用されている』という理由でシュッと閉じられた

Bug #16942 instance_method causes an infinite loop with prepend, include and private

  • 特定の mixin を行った状態で Object.instance_method を呼ぶと無限ループするバグ
module M
  def x
  end
end

module M2
  include M
  private :x
end

::Object.prepend(M2)

# infinite loop
p Object.instance_method(:x)
  • 上の例だと Ruby 2.7.1 では無限ループしないが 2.8.0dev だと無限ループする
  • 下の例だと Ruby 2.7.1 でも無限ループする
module M
  def x
  end
end

module M2
  include M
  private :x
  prepend Module.new
end

::Object.prepend(M2)

# infinite loop
p Object.instance_method(:x)