Skip to content

Commit

Permalink
make fallthrough accessors compatible with ruby 3
Browse files Browse the repository at this point in the history
`method_missing` does not swallow kwargs on ruby 3 anymore
  • Loading branch information
doits committed Jul 30, 2021
1 parent 2871898 commit 73c9afd
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/mobility.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ class Comment
plugin enabled.
=end

def ruby2_keywords(*); end unless respond_to?(:ruby2_keywords, true)

module Mobility
# A generic exception used by Mobility.
class Error < StandardError
Expand Down
7 changes: 7 additions & 0 deletions lib/mobility/plugins/fallthrough_accessors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ def define_fallthrough_accessors(*names)
end
end

# Following is needed in order to not swallow `kwargs` on ruby >= 3.0.
# Otherwise `kwargs` are not passed by `super` to a possible other
# `method_missing` defined like this:
#
# def method_missing(name, *args, **kwargs, &block); end
ruby2_keywords :method_missing

define_method :respond_to_missing? do |method_name, include_private = false|
(method_name =~ method_name_regex) || super(method_name, include_private)
end
Expand Down
16 changes: 16 additions & 0 deletions spec/mobility/plugins/fallthrough_accessors_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ def method_missing(method_name, *args, &block)
expect(instance.foo(**options)).to eq([options])
end

it 'passes kwargs to super when method does not match' do
mod = Module.new do
def method_missing(method_name, *args, **kwargs, &block)
(method_name == :foo) ? [args, kwargs] : super
end
end

model_class = Class.new
model_class.include translations, mod

instance = model_class.new

kwargs = { some: 'params' }
expect(instance.foo(**kwargs)).to eq([[], kwargs])
end

it 'does not pass on empty keyword options hash to super' do
mod = Module.new do
def method_missing(method_name, *args, &block)
Expand Down

0 comments on commit 73c9afd

Please sign in to comment.