今週の気になった bugs.ruby

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

[Feature #17043] Invokable module for custom Proc-like objects

  • 『Proc なオブジェクト』を明示化できるモジュールの追加案
    • Invokable というモジュールを追加する
    • gem : https://github.com/delonnewman/invokable
    • このモジュールを include することで暗黙的に #to_proc #curry #<< #>> などが定義される
class String
  # 暗黙的に to_proc や curry などが定義される
  include Invokable

  def call(...)
    to_sym.to_proc.call(...)
  end
end

p "size".call [1, 2, 3]
# => 3

p ["a", "bb", "ccc"].map(&"size")
# => [1, 2, 3]
  • 便利そうではあるけど、実用的に使うケースはそんなにないような気もする
    • ただ、明示的に Invokable であることを宣言できる機能としてはちょっと欲しい
  • gem 化されているのであればそれを使えばいいのでは…?

[Bug #17038] On master, ancestry edits can lead to duplicates in Module#ancestors

  • #9573 の影響で以下のように継承リストに同じモジュールが重複するようになったという報告
module A
  def foo
    [:a] + super
  end
end

module B
  def foo
    [:b] + super
  end
end

class Object
  def foo
    [:object]
  end
end

module C
  def foo
    [:c] + super
  end
end

class D
  prepend A
  include C
  include B


  def foo
    [:d] + super
  end
end

B.include A
C.include A

# 同じモジュールが複数ある
p D.ancestors
# => [A, D, B, A, C, A, Object, Kernel, BasicObject]

# 同じメソッドが複数回呼ばれる
p D.new.foo
# => [:a, :d, :b, :a, :c, :a, :object]

[[Feature #11689] Add methods allow us to get visibility from Method and UnboundMethod object.]

class Object
  def debugging(name)
    original = instance_method(name)

    # 提案
    method_visibility = original.visibility
    # 既存の実装だとこう書く必要がある
    # method_visibility = if private_method_defined?(name)
    #                       :private
    #                     elsif protected_method_defined?(name)
    #                       :protected
    #                     else
    #                       :public
    #                     end
    define_method(name) { |*args, &block|
      pp name
      original.bind(self).call(*args, &block)
    }

    # 元のメソッドに合わせる
    send(method_visibility, name)
  end
end

class X
  def hoge
    pp 1 + 2
  end
  private :hoge

  debugging :hoge
end

# error: private method `hoge' called for #<X:0x000055f0b1abf3e0> (NoMethodError)
X.new.hoge