diff options
author | Michael Kozono <mkozono@gmail.com> | 2018-09-28 01:03:42 +0300 |
---|---|---|
committer | Michael Kozono <mkozono@gmail.com> | 2018-09-28 04:22:37 +0300 |
commit | f2fa7c10c8490a31863c9bd21bbfd66675e3c909 (patch) | |
tree | 62f47f89ceea7afa60326a704181d2c7fb1cf81f /lib | |
parent | f807ea334b83526e51d738460edccc2a0651e1c6 (diff) |
Remove send-in-send for safety and readability
I attempted to refactor so that the caller of `wrap_method` passes in a
block, rather than a method name, but I was unsuccessful.
I kept getting the following error:
NoMethodError:
undefined method `cache_method_output' for Repository:Class
If you can figure this out, then feel free to dry up these class methods
again without doing a send-within-a-send.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/repository_cache_adapter.rb | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/lib/gitlab/repository_cache_adapter.rb b/lib/gitlab/repository_cache_adapter.rb index 160e3d13b43..d95024fccf7 100644 --- a/lib/gitlab/repository_cache_adapter.rb +++ b/lib/gitlab/repository_cache_adapter.rb @@ -12,7 +12,13 @@ module Gitlab # fallback - A value to fall back to if the repository does not exist, or # in case of a Git error. Defaults to nil. def cache_method(name, fallback: nil) - wrap_method(name, :cache_method_output, fallback: fallback) + uncached_name = alias_uncached_method(name) + + define_method(name) do + cache_method_output(name, fallback: fallback) do + __send__(uncached_name) # rubocop:disable GitlabSecurity/PublicSend + end + end end # Caches truthy values from the method. All values are strongly memoized, @@ -26,7 +32,13 @@ module Gitlab # # name - The name of the method to be cached. def cache_method_asymmetrically(name) - wrap_method(name, :cache_method_output_asymmetrically) + uncached_name = alias_uncached_method(name) + + define_method(name) do + cache_method_output_asymmetrically(name) do + __send__(uncached_name) # rubocop:disable GitlabSecurity/PublicSend + end + end end # Strongly memoizes the method. @@ -38,22 +50,25 @@ module Gitlab # in case of a Git error. Defaults to nil. The fallback value # is not memoized. def memoize_method(name, fallback: nil) - wrap_method(name, :memoize_method_output, fallback: fallback) - end - - # Prepends "_uncached_" to the target method name, and redefines the method - # but wraps it in the `wrapper` method. - def wrap_method(name, wrapper, *options) - original = :"_uncached_#{name}" - - alias_method(original, name) + uncached_name = alias_uncached_method(name) define_method(name) do - __send__(wrapper, name, *options) do # rubocop:disable GitlabSecurity/PublicSend - __send__(original) # rubocop:disable GitlabSecurity/PublicSend + memoize_method_output(name, fallback: fallback) do + __send__(uncached_name) # rubocop:disable GitlabSecurity/PublicSend end end end + + # Prepends "_uncached_" to the target method name + # + # Returns the uncached method name + def alias_uncached_method(name) + uncached_name = :"_uncached_#{name}" + + alias_method(uncached_name, name) + + uncached_name + end end # RequestStore-backed RepositoryCache to be used. Should be overridden by |