48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
# File 'lib/perma_cache.rb', line 48
def perma_cache(original_name, options = {})
options.symbolize_keys!
valid_keys = [:expires_in, :obj, :version]
raise "expected keys are #{valid_keys}" if (options.keys - valid_keys).present?
class_eval do
regex = /[\?\!]\Z/
method_name = original_name.to_s.gsub("!", "_exclamation").gsub("?", "_question")
method_base = original_name.to_s.gsub(regex,'')
method_suffix = original_name.to_s.match(regex)
was_rebuilt_inst_var = "@#{method_name}_was_rebuilt"
define_method "#{method_name}_base_key" do
key = []
key << "perma_cache"
key << "v#{PermaCache.version}"
key << PermaCache.build_key_from_object(self)
if options[:obj]
key << PermaCache.build_key_from_object(send(options[:obj]))
end
if options[:version]
key << "v#{options[:version]}"
end
key
end
define_method "#{method_name}_perma_cache_key" do
[
send("#{method_name}_base_key"),
(send("#{method_name}_key") rescue nil),
method_name
].flatten.compact.map(&:to_s).reject{|k| k.empty?}.join('/').gsub(' ','_')
end
define_method "#{method_name}!" do
instance_variable_set(was_rebuilt_inst_var , true)
send("#{method_base}_without_perma_cache#{method_suffix}").tap do |result|
PermaCache.cache.write(send("#{method_name}_perma_cache_key"), result, :expires_in => options[:expires_in])
end
end
define_method "#{method_name}_get_perma_cache" do
PermaCache.cache.read(send("#{method_name}_perma_cache_key"))
end
with_perma_cache_method_name = "#{method_base}_with_perma_cache#{method_suffix}"
define_method with_perma_cache_method_name do
instance_variable_set(was_rebuilt_inst_var , false)
send("#{method_name}_get_perma_cache") ||
(
instance_variable_set(was_rebuilt_inst_var , true) &&
send("#{method_name}!")
)
end
define_method "#{method_name}_was_rebuilt?" do
instance_variable_get(was_rebuilt_inst_var ) == true
end
base_name = [method_base, method_suffix].join
alias_method [[method_base, 'without', 'perma_cache'].compact.join('_'), method_suffix].join, base_name
alias_method base_name, with_perma_cache_method_name
end
end
|