class Module
def once_with_args(*methods)
methods.each do |m|
class_eval <<-"END_OF_EVAL"
alias_method :__once_with_args__#{m.to_i}__, :#{m.to_s}
private :__once_with_args__#{m.to_i}__
def #{m.to_s}(*args, &block)
fail "Object shoul be frozen" unless frozen?
fail "Block handling is not yet implemented in once_with_args" if block_given?
@@__once_with_args__ ||= {}
@@__once_with_args__[#{m.to_i}] ||= {}
@@__once_with_args__[#{m.to_i}][args] ||= __once_with_args__#{m.to_i}__(*args)
# We should handle &block as parameter, since it might be different each time. I don't know how to do this...
end
END_OF_EVAL
end
end
end
class Foo
def calc1(a,b,c)
p [:org_calc1, [a, b, c]] # DEBUG
1 #same complicated, time-consuming calculation...
end
def calc2(a,b)
p [:org_calc2, [a, b]] # DEBUG
2 #same complicated, time-consuming calculation...
end
once_with_args :calc1
once_with_args :calc2
end