From: Frank Tao Date: 2008-12-04T04:59:15+09:00 Subject: Re: dynamic programming 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/.