summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Kozono <mkozono@gmail.com>2018-09-27 15:03:42 -0700
committerMichael Kozono <mkozono@gmail.com>2018-09-27 18:22:37 -0700
commitf2fa7c10c8490a31863c9bd21bbfd66675e3c909 (patch)
tree62f47f89ceea7afa60326a704181d2c7fb1cf81f
parentf807ea334b83526e51d738460edccc2a0651e1c6 (diff)
downloadgitlab-ce-f2fa7c10c8490a31863c9bd21bbfd66675e3c909.tar.gz
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.
-rw-r--r--lib/gitlab/repository_cache_adapter.rb41
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