Module: Locale::Util::Memoizable

Included in:
Locale, Tag, Tag::Cldr, Tag::Common, Tag::Rfc, Tag::Simple, Tag::Simple, TagList
Defined in:
lib/locale/util/memoizable.rb

Constant Summary collapse

MEMOIZED_IVAR =
Proc.new do |symbol| 
  "#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}".to_sym
end

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



14
15
16
17
18
19
# File 'lib/locale/util/memoizable.rb', line 14

def self.included(base)
  mod = self
  base.class_eval do
    extend mod
  end
end

Instance Method Details

#_memoize(ivar, key) ⇒ Object

:nodoc:



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/locale/util/memoizable.rb', line 81

def _memoize(ivar, key) #:nodoc:
  @_memoized_ivars ||= {}
  @_memoized_ivars[ivar] ||= {}

  ret = @_memoized_ivars[ivar][key]
  unless ret
    ret = yield
    ret.freeze
    @_memoized_ivars[ivar][key] = ret 
  end
  ret
end

#_memoize_dup(ivar, key) ⇒ Object

:nodoc:



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/locale/util/memoizable.rb', line 94

def _memoize_dup(ivar, key) #:nodoc:
  ret = _memoize(ivar, key) do; yield; end
  if ret
    if ret.kind_of? Array
      ret.map{|v| v.dup}.dup
    else
      ret.dup
    end
  else
    nil
  end
end

#clearObject

Clear memoized values. Deprecated.



30
31
32
# File 'lib/locale/util/memoizable.rb', line 30

def clear  # :nodoc: 
  @_memoized_ivars = {}
end

#freezeObject

:nodoc:



22
23
24
25
26
27
# File 'lib/locale/util/memoizable.rb', line 22

def freeze #:nodoc:
  unless frozen?
    @_memoized_ivars = {}
    freeze_without_memoizable
  end
end

#freeze_without_memoizableObject

:nodoc:



21
# File 'lib/locale/util/memoizable.rb', line 21

alias :freeze_without_memoizable :freeze

#memoize(*symbols) ⇒ Object

Cache the result of the methods.

include Memoizable
def foo
  ......
end
def bar(a, b)
  ......
end
memoize :foo, :bar(a, b)

To clear cache, #clear_foo, #clear_bar is also defined.

(NOTE)

  • Consider to use this with huge objects to avoid memory leaks.

  • Can’t use this with super.<method> because of infinity loop.



55
56
57
# File 'lib/locale/util/memoizable.rb', line 55

def memoize(*symbols)
  memoize_impl(false, *symbols)
end

#memoize_clearObject

Clear memoized values.



35
36
37
# File 'lib/locale/util/memoizable.rb', line 35

def memoize_clear
  @_memoized_ivars = {}
end

#memoize_dup(*symbols) ⇒ Object

memoize with dup. A copy object is returned.



60
61
62
# File 'lib/locale/util/memoizable.rb', line 60

def memoize_dup(*symbols)
  memoize_impl(true, *symbols)
end

#memoize_impl(is_dup, *symbols) ⇒ Object

:nodoc:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/locale/util/memoizable.rb', line 64

def memoize_impl(is_dup, *symbols) #:nodoc:
  symbols.each do |symbol|
    original_method = "_unmemoized_#{symbol}"
    memoized_ivar = MEMOIZED_IVAR.call(symbol)
    dup_meth = is_dup ? "_dup" : ""

    class_eval <<-EOS, __FILE__, __LINE__
      alias #{original_method} #{symbol}
      def #{symbol}(*args)
        _memoize#{dup_meth}(:#{memoized_ivar}, args.hash) do
          #{original_method}(*args)
        end
      end
    EOS
  end
end