Project

General

Profile

Backport #5270 » date-once.patch

Patch that fixes the issue - ddfreyne (Denis Defreyne), 09/03/2011 05:13 PM

View differences:

lib/date.rb
class << self
def once(*ids) # :nodoc:
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)
(@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0]
end
end;
def once(*meths)
meths.each do |meth|
# Alias
orig_meth = '__nonmemoized_' + meth.to_s
alias_method orig_meth, meth
# Redefine
define_method(meth) do |*args|
# Get cache
@__memoization_cache ||= {}
@__memoization_cache[meth] ||= {}
# Recalculate or fetch
cache = @__memoization_cache[meth]
if !cache.has_key?(args)
cache[args] = send(orig_meth, *args)
else
result = cache[args]
end
end
end
end
......
#
# Using one of the factory methods such as Date::civil is
# generally easier and safer.
def initialize(ajd=0, of=0, sg=ITALY) @ajd, @of, @sg = ajd, of, sg end
def initialize(ajd=0, of=0, sg=ITALY)
@ajd, @of, @sg = ajd, of, sg
@__memoization_cache = {}
end
# Get the date as an Astronomical Julian Day Number.
def ajd() @ajd end
test/ruby/test_date.rb
require 'test/unit'
require 'date'
class TestDate < Test::Unit::TestCase
def test_freeze
foo = Date.new
foo.freeze
foo.year
end
end
(2-2/2)