diff --git a/lib/memoist.rb b/lib/memoist.rb index c49e102..03c28d7 100644 --- a/lib/memoist.rb +++ b/lib/memoist.rb @@ -203,7 +203,7 @@ def #{method_name}(reload = false) # end module_eval <<-EOS, __FILE__, __LINE__ + 1 - def #{method_name}(*args) + ruby2_keywords def #{method_name}(*args) reload = Memoist.extract_reload!(method(#{unmemoized_method.inspect}), args) skip_cache = reload || !(instance_variable_defined?(#{memoized_ivar.inspect}) && #{memoized_ivar} && #{memoized_ivar}.has_key?(args)) diff --git a/memoist.gemspec b/memoist.gemspec index 3b6fb30..7474e24 100644 --- a/memoist.gemspec +++ b/memoist.gemspec @@ -37,10 +37,15 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'benchmark-ips' spec.add_development_dependency 'bundler' + spec.add_development_dependency 'minitest', '~> 5.10' + if RUBY_VERSION < '1.9.3' spec.add_development_dependency 'rake', '~> 10.4' else spec.add_development_dependency 'rake' end - spec.add_development_dependency 'minitest', '~> 5.10' + + if RUBY_VERSION < '3.0.0' + spec.add_dependency 'ruby2_keywords' + end end diff --git a/test/memoist_test.rb b/test/memoist_test.rb index 28551a5..0301ad8 100644 --- a/test/memoist_test.rb +++ b/test/memoist_test.rb @@ -74,9 +74,40 @@ def update_attributes(_options = {}) end memoize :update_attributes - def update_attributes_calls - @counter.count(:update_attributes) + def rest(*args) + counter.call(:rest) + + args.each_with_index.each_with_object({}) do |(arg, i), memo| + memo[i + 1] = arg + end + end + memoize :rest + + def rest_and_kwargs(*args, **options) + counter.call(:rest_and_kwargs) + + i = 0 + + rest = args.each_with_object({}) do |arg, memo| + memo[i += 1] = arg + end + + kwargs = options.each_with_object({}) do |(key, value), memo| + memo[i += 1] = [key, value] + end + + { rest: rest, kwargs: kwargs } + end + memoize :rest_and_kwargs + + def kwargs(**options) + counter.call(:kwargs) + + options.each_with_index.each_with_object({}) do |((key, value), i), memo| + memo[i += 1] = [key, value] + end end + memoize :kwargs protected @@ -338,7 +369,7 @@ def test_all_memoized_structs # Student < Person memoize :name, :identifier => :student # Teacher < Person memoize :seniority - expected = %w[age age? is_developer? memoize_protected_test name name? sleep update update_attributes] + expected = %w[age age? is_developer? memoize_protected_test name name? sleep update update_attributes rest rest_and_kwargs kwargs].sort structs = Person.all_memoized_structs assert_equal expected, structs.collect(&:memoized_method).collect(&:to_s).sort assert_equal '@_memoized_name', structs.detect { |s| s.memoized_method == :name }.ivar @@ -537,4 +568,49 @@ def test_private_method_memoization assert_equal 'Yes', person.send(:is_developer?) assert_equal 1, person.calls(:is_developer?) end + + def test_rest + person = Person.new + + 3.times do + assert_equal({ 1 => :one, 2 => :two, 3 => :three }, person.rest(:one, :two, :three)) + end + + assert_equal 1, person.calls(:rest) + end + + def test_rest_and_kwargs + person = Person.new + + 3.times do + assert_equal({ + rest: { + 1 => :one, + 2 => :two, + 3 => :three + }, + kwargs: { + 4 => [:four, :five], + 5 => [:six, :seven] + } + }, + person.rest_and_kwargs(:one, :two, :three, four: :five, six: :seven)) + end + + assert_equal 1, person.calls(:rest_and_kwargs) + end + + def test_kwargs + person = Person.new + + 3.times do + assert_equal({ + 1 => [:four, :five], + 2 => [:six, :seven] + }, + person.kwargs(four: :five, six: :seven)) + end + + assert_equal 1, person.calls(:kwargs) + end end