Friday, July 06, 2007

CLASS AND MODULE DEFINITIONS[programming ruby 2nd]


# 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 :