diff --git a/Steepfile b/Steepfile index 60689d543..b00e4542b 100644 --- a/Steepfile +++ b/Steepfile @@ -15,6 +15,7 @@ target :lib do signature "stdlib/rdoc/0/" signature "stdlib/ripper/0" signature "stdlib/pp/0" + signature "steep/patch.rbs" # configure_code_diagnostics do |config| # config[D::Ruby::MethodDefinitionMissing] = :hint diff --git a/core/module.rbs b/core/module.rbs index c5e43339c..b585bc43c 100644 --- a/core/module.rbs +++ b/core/module.rbs @@ -1646,6 +1646,43 @@ class Module < Object # def remove_method: (*interned arg0) -> self + # + # For the given method names, marks the method as passing keywords through a + # normal argument splat. This should only be called on methods that accept an + # argument splat (`*args`) but not explicit keywords or a keyword splat. It + # marks the method such that if the method is called with keyword arguments, the + # final hash argument is marked with a special flag such that if it is the final + # element of a normal argument splat to another method call, and that method + # call does not include explicit keywords or a keyword splat, the final element + # is interpreted as keywords. In other words, keywords will be passed through + # the method to other methods. + # + # This should only be used for methods that delegate keywords to another method, + # and only for backwards compatibility with Ruby versions before 3.0. See + # https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyw + # ord-arguments-in-ruby-3-0/ for details on why `ruby2_keywords` exists and when + # and how to use it. + # + # This method will probably be removed at some point, as it exists only for + # backwards compatibility. As it does not exist in Ruby versions before 2.7, + # check that the module responds to this method before calling it: + # + # module Mod + # def foo(meth, *args, &block) + # send(:"do_#{meth}", *args, &block) + # end + # ruby2_keywords(:foo) if respond_to?(:ruby2_keywords, true) + # end + # + # However, be aware that if the `ruby2_keywords` method is removed, the behavior + # of the `foo` method using the above approach will change so that the method + # does not pass through keywords. + # + private def ruby2_keywords: (*interned method_name) -> nil + # + # Marks the proc as passing keywords through a normal argument splat. This + # should only be called on procs that accept an argument splat (`*args`) but not + # explicit keywords or a keyword splat. It marks the proc such that if the proc + # is called with keyword arguments, the final hash argument is marked with a + # special flag such that if it is the final element of a normal argument splat + # to another method call, and that method call does not include explicit + # keywords or a keyword splat, the final element is interpreted as keywords. In + # other words, keywords will be passed through the proc to other methods. + # + # This should only be used for procs that delegate keywords to another method, + # and only for backwards compatibility with Ruby versions before 2.7. + # + # This method will probably be removed at some point, as it exists only for + # backwards compatibility. As it does not exist in Ruby versions before 2.7, + # check that the proc responds to this method before calling it. Also, be aware + # that if this method is removed, the behavior of the proc will change so that + # it does not pass through keywords. + # + # module Mod + # foo = ->(meth, *args, &block) do + # send(:"do_#{meth}", *args, &block) + # end + # foo.ruby2_keywords if foo.respond_to?(:ruby2_keywords) + # end + # + def ruby2_keywords: () -> self + #