16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/memoized.rb', line 16
def memoize(*method_names)
method_names.each do |method_name|
memoized_ivar_name = Memoized.ivar_name(method_name)
unmemoized_method = "_unmemoized_#{method_name}"
alias_method unmemoized_method, method_name
arity = instance_method(unmemoized_method).arity
if arity == 0
module_eval(<<-RUBY)
def #{method_name}()
#{memoized_ivar_name} ||= [#{unmemoized_method}()]
#{memoized_ivar_name}.first
end
RUBY
elsif arity == -1
module_eval(<<-RUBY)
def #{method_name}(*args)
#{memoized_ivar_name} ||= {}
if #{memoized_ivar_name}.has_key?(args)
#{memoized_ivar_name}[args]
else
#{memoized_ivar_name}[args] = #{unmemoized_method}(*args)
end
end
RUBY
elsif arity < -1
required_arg_names = (1..(-arity - 1)).map { |i| "arg#{i}" }
required_args_ruby = required_arg_names.join(', ')
module_eval(<<-RUBY)
def #{method_name}(#{required_args_ruby}, *optional_args)
all_args = [#{required_args_ruby}, *optional_args]
#{memoized_ivar_name} ||= {}
if #{memoized_ivar_name}.has_key?(all_args)
#{memoized_ivar_name}[all_args]
else
#{memoized_ivar_name}[all_args] = #{unmemoized_method}(*all_args)
end
end
RUBY
else arg_names = (1..arity).map { |i| "arg#{i}" }
args_ruby = arg_names.join(', ')
module_eval(<<-RUBY)
def #{method_name}(#{args_ruby})
all_args = [#{args_ruby}]
#{memoized_ivar_name} ||= {}
if #{memoized_ivar_name}.has_key?(all_args)
#{memoized_ivar_name}[all_args]
else
#{memoized_ivar_name}[all_args] = #{unmemoized_method}(#{args_ruby})
end
end
RUBY
end
if self.private_method_defined?(unmemoized_method)
private method_name
elsif self.protected_method_defined?(unmemoized_method)
protected method_name
end
end
end
|