ruby-deprecate_public exists so that library authors can take an existing public method in one of their classes, and make it a private method, but still allow it to be called as a public method, emitting a warning if called as a public method.
On Ruby 2.6+, you can also take an existing public constant, make it a private constant, but still allow it to be accessed as a public constant, emitting a warning if accessed as a public constant.
require 'deprecate_public' class Foo private def meth :return_value end end foo = Foo.new foo.send(:meth) # => :return_value foo.meth # raises NoMethodError: private method `meth' called for ... Foo.deprecate_public :meth foo.meth # warning emitting: "calling Foo#meth using deprecated public interface" # => :return_value ## Ruby 2.6+: Deprecating Constants class Foo BAR = 1 private_constant :BAR end Foo::BAR # raises NameError: private constant Foo::BAR referenced Foo.deprecate_public_constant :Bar Foo::BAR # warning emitting: "accessing Foo::BAR using deprecated public interface" # => 1
# Deprecate multiple methods at once deprecate_public([:meth1, :meth2]) # Override message deprecate_public(:meth1, "meth1 is private method, stop calling it!") # Ruby 2.6+: deprecate_public_constant uses same interface
deprecate_public
works by overriding method_missing
, which is called if you call a private method with a specified receiver. That’s one of the reasons calling a private method raises NoMethodError
instead of MethodVisibilityError
or something like that.
On Ruby 2.6+, deprecate_public_constant
works by overriding const_missing
, which is called if you access a constant using the public interface (Foo::BAR
in the above example).
Before Ruby 3, while you can call deprecate_public
on a Module, you should only do so if the module has not been included in another Module or Class, as when called on a module it only affects future cases where the module was included in a class.
While you can call deprecate_public_constant
on a Module, you should only do so if the module has not been included in another Module or Class, as when called on a module it only affects future cases where the module was included in a class, even in Ruby 3.
ruby-deprecate_public is distributed as a gem, and can be installed with:
gem install deprecate_public
ruby-deprecate_public is hosted on GitHub:
https://github.com/jeremyevans/ruby-deprecate_public
ruby-deprecate_public uses GitHub Issues for issue tracking:
https://github.com/jeremyevans/ruby-deprecate_public/issues
Jeremy Evans <code@jeremyevans.net>