Madogiwa Blog

主に技術系の学習メモに使っていきます。

Ruby: 外部からprivateなメソッドをpublicにする方法メモ📝

好ましくはないですが、通常Rubyでprivateなメソッドを呼び出したい時にはsendを使うケースが多いです。

docs.ruby-lang.org

しかしライブラリの破壊的変更等によりpublicだっだメソッドがprivateになる等、すでに大量に依存しているケースですべてをsendに直すのは大変なケースもあります。

そういうケースではModule#publicを使うと任意のprivateメソッドをpublicにできて便利だったので使い方をメモ📝

docs.ruby-lang.org

当たり前ですが、以下の実装はprivate methodprivate_foo' called for an instance of Foo (NoMethodError)`が発生し、エラーになります。

class Foo
  def public_foo
    puts "public_foo"
  end

  private

  def private_foo
    puts "private_foo"
  end
end

puts Foo.new.private_foo
#=> test.rb:17:in `<main>': private method `private_foo' called for an instance of Foo (NoMethodError)
# puts Foo.new.private_foo
#            ^^^^^^^^^^^^
# Did you mean?  private_methods

しかし、以下のような感じでpublic :private_fooを使うと外からpublicなメソッドに変更することができます。

class Foo
  def public_foo
    puts "public_foo"
  end

  private

  def private_foo
    puts "private_foo"
  end
end

Foo.class_eval { public :private_foo }

puts Foo.new.private_foo
# => private_foo

使い所は気をつける必要がありますが、実装を外部から柔軟にコントロールできるのはRuby便利💎✨