Frank Tao wrote:
# I have a class Adam
# I want to modify the method("m_a") so that it will return the cached
result
# If no cached result is available, then return the original result
# I want to create a class method(AKA: macro) to make it DRY
#
# So far, I have issues like
# 1) dynmically define class variable
# 2) failed to include a module inside a method of a class
#
# Any suggestion or comments will be appreciated
#
class Adam
def self.m_a
["Adam#m_a"]
end
end
class CachedAdam
caching_method :adam, :m_a
def self.caching_method
# this method should do something to make the following codes
end
end
## CachedAdam#caching_method should make and load the following codes
#
# module AdamWithCache
# def m_a_with_cache
# CachedAdam.get_cached_m_a || m_a_without_cache
# end
# def self.include(base)
# base.alias_method_chain :m_a, :cache
# end
# end
# Adam.class_eval{ include AdamWithCache }
#
# class CachedAdam
# def self.get_cached_m_a( adam_id )
# @@cache && @@cache[adam_id]
# end
#
# def self.set_cached_m_a(hash_list)
# hash_list.each do |k,v|
# @@cache ||={} # failed, any suggestion?
# @@cache[k] = v
# end
# end
# end
THANKS FOR YOUR HELPFUL RESPONSE. I FOUND THAT MY ORIGINAL HAD SOME
MISTAKES AND THEREFORE DID NOT REFLECT EXACTLY WHAT I WANT.
SO I UPDATE IT AS FOLLOWS:
class Adam
def m_a
"a"
end
end
class CachedMethod
@@cached_variables = {}
def self.caching_method(model, method)
model, method = model.to_s, method.to_s
@@cached_variables["#{model}_#{method}_cache"] = {}
(class << self; self; end).instance_eval do
define_method "set_cached_#{model}_#{method}" do |hash_list|
hash_list.each do |k,v|
@@cached_variables["#{model}_#{method}_cache"][k] = v
end
end
define_method "get_cached_#{model}_#{method}" do |model_id|
@@cached_variables["#{model}_#{method}_cache"] &&
@@cached_variables["#{model}_#{method}_cache"][model_id]
end
end
···
#
# Purpose: create a module and let it be included by Adam class
# NOT WORKING, any suggestion?
self.class_eval <<-EOD
module AdamWithCache
def m_a_with_cache
CachedMethod.get_cached_adam_m_a(self.id) || m_a_without_cache
end
def self.include(base)
base.alias_method_chain :m_a, :cache
end
end
Adam.class_eval{ include AdamWithCache }
EOD
end
def self.reset
@@cached_variables = {}
end
self.caching_method :adam, :m_a
end
#module AdamWithCache
# def m_a_with_cache
# CachedMethod.get_cached_adam_m_a(self.id) || m_a_without_cache
# end
# def self.include(base)
# base.alias_method_chain :m_a, :cache
# end
#end
#Adam.class_eval{ include AdamWithCache }
#
#Example usage:
#=============================================
puts @adam_1 = Adam.new #==> assume: @adam.id == 1
puts @adam_2 = Adam.new #==> assume: @adam.id == 2
puts @adam_3 = Adam.new #==> assume: @adam.id == 3
puts @adam_1.m_a #==> "a"
puts @adam_2.m_a #==> "a"
puts @adam_3.m_a #==> "a"
puts @adam_1.id #==> 1
puts @adam_2.id #==> 2
puts @adam_3.id #==> 3
hash_list = {@adam_1.id => "b", @adam_2.id => "c"}
CachedMethod.set_cached_adam_m_a(hash_list)
puts CachedMethod.get_cached_adam_m_a(@adam_1.id) #==> "b"
puts @adam_1.m_a #==> "b" !!! DID NOT OUTPUT AS I EXPECTED
puts @adam_2.m_a #==> "c" !!! DIDO
puts @adam_3.m_a #==> "a" !!! DIDO
CachedMethod.reset
puts @adam_1.m_a #==> "a"
puts @adam_2.m_a #==> "a"
puts @adam_3.m_a #==> "a"
--
Posted via http://www.ruby-forum.com/\.