# programming ruby 2nd
# CLASS AND MODULE DEFINITIONS 373
class OnceTest
  
  # @__#{id.to_i}__ = [__#{id.to_i}__(*args, &block)]
  def OnceTest.once(*ids)
  for id in ids
   module_eval <<-"end;"
    alias_method :__#{id.to_i}__, :#{id.to_s}
       
    private :__#{id.to_i}__
       
    def #{id.to_s}(*args, &block)
      if @__#{id.to_i}__
        puts 'exist cache'
            puts @__#{id.to_i}__.inspect
      end
      (@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0]
    end
       
   end;
  end
 end
 
 def p1
   # complex process
   puts 'p1'
   return 1
    # the body of a particular method should be invoked only once, The value returned by that first call should be cached.
 end
  def p2
   # complex process
   puts 'p2'
    return 2
    # 方法体内语句只会执行一次,方法返回的结果会被缓存。
  end
    
 once :p1, :p2 
  # 这些方法都要在此语句之前定义
  # 原来的p1和p2方法在once里被重新定义了一个同名方法
  # 原来方法名被改为__#{id.to_i}__,格式如:(__nnn__)
  # 在once方法体里将原来方法调用后生成的结果放到@__#{id.to_i}__这个实例变量中
  # 第二次调用相同方法体时,直接返回@__#{id.to_i}__
end
o = OnceTest.new
3.times do |i| 
  o.p1
  o.p2
end
#p1
#p2
#exist cache
#[1]
#exist cache
#[2]
#exist cache
#[1]
#exist cache
#[2]
 
No comments :
Post a Comment