From 825d57d6c339b33322be894690a9fbfa864f0e81 Mon Sep 17 00:00:00 2001 From: Alexander Smirnov Date: Thu, 17 Dec 2015 13:07:41 +0300 Subject: [PATCH] closes https://github.com/matthewrudy/memoist/issues/39 --- .gitignore | 1 + lib/memoist.rb | 23 +++++++++++++++++++++-- lib/memoist/blocks_not_supported.rb | 4 ++++ test/memoist_test.rb | 16 ++++++++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 lib/memoist/blocks_not_supported.rb 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 7e0774c..d2cefc3 100644 --- a/lib/memoist.rb +++ b/lib/memoist.rb @@ -1,4 +1,5 @@ require 'memoist/core_ext/singleton_class' +require 'memoist/blocks_not_supported' module Memoist @@ -109,7 +110,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 @@ -157,7 +164,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? @@ -199,7 +212,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