diff --git a/.gitignore b/.gitignore index d87d4be..555aadd 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ spec/reports test/tmp test/version_tmp tmp +.ruby-version diff --git a/lib/memoist.rb b/lib/memoist.rb index 88b7ff2..a007c4e 100644 --- a/lib/memoist.rb +++ b/lib/memoist.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'memoist/version' require 'memoist/core_ext/singleton_class' +require 'memoist/blocks_not_supported' module Memoist @@ -111,7 +112,13 @@ def clear_structs @all_memoized_structs = nil end + def memoize_caller + caller.find { |x| !x['lib/memoist.rb'] } + end + def memoize(*method_names) + memoize_caller = self.memoize_caller + if method_names.last.is_a?(Hash) identifier = method_names.pop[:identifier] end @@ -159,7 +166,13 @@ def self.memoized_methods # end module_eval <<-EOS, __FILE__, __LINE__ + 1 - def #{method_name}(reload = false) + def #{method_name}(reload = false, &block) + if block + raise Memoist::BlocksNotSupported, + "Calls with block is not alowed for memoized method #{method_name}\n" \ + "memoist called at #{memoize_caller}" + end + skip_cache = reload || !instance_variable_defined?("#{memoized_ivar}") set_cache = skip_cache && !frozen? @@ -201,7 +214,13 @@ def #{method_name}(reload = false) # end module_eval <<-EOS, __FILE__, __LINE__ + 1 - def #{method_name}(*args) + def #{method_name}(*args, &block) + if block + raise Memoist::BlocksNotSupported, + "Calls with block is not alowed for memoized method #{method_name}\n" \ + "memoist called at #{memoize_caller}" + end + 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/lib/memoist/blocks_not_supported.rb b/lib/memoist/blocks_not_supported.rb new file mode 100644 index 0000000..d84e725 --- /dev/null +++ b/lib/memoist/blocks_not_supported.rb @@ -0,0 +1,4 @@ +module Memoist + # Memoist does not support calls with block to cached method_names + BlocksNotSupported = Class.new(StandardError) +end diff --git a/test/memoist_test.rb b/test/memoist_test.rb index a666d06..d103a66 100644 --- a/test/memoist_test.rb +++ b/test/memoist_test.rb @@ -461,4 +461,20 @@ def test_private_method_memoization assert_equal 1, person.is_developer_calls end + def test_blocks_supported + person = Person.new + + assert_raises(Memoist::BlocksNotSupported) { person.name { :block } } + assert_raises(Memoist::BlocksNotSupported) { person.update('smth') { :block } } + end + + def test_block_contains_proper_caller + person = Person.new + + begin + person.name { :block } + rescue Memoist::BlocksNotSupported => e + assert(e.message =~ /memoist_test.rb:\d+/, "message should contain caller of memoize") + end + end end