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(" def \#{method_name}()\n \#{memoized_ivar_name} ||= [\#{unmemoized_method}()]\n \#{memoized_ivar_name}.first\n end\n RUBY\n\n elsif arity == -1\n module_eval(<<-RUBY)\n def \#{method_name}(*args)\n \#{memoized_ivar_name} ||= {}\n if \#{memoized_ivar_name}.has_key?(args)\n \#{memoized_ivar_name}[args]\n else\n \#{memoized_ivar_name}[args] = \#{unmemoized_method}(*args)\n end\n end\n RUBY\n\n elsif arity < -1\n # For Ruby methods that take a variable number of arguments,\n # Method#arity returns -n-1, where n is the number of required arguments\n required_arg_names = (1..(-arity - 1)).map { |i| \"arg\#{i}\" }\n required_args_ruby = required_arg_names.join(', ')\n\n module_eval(<<-RUBY)\n def \#{method_name}(\#{required_args_ruby}, *optional_args)\n all_args = [\#{required_args_ruby}, *optional_args]\n \#{memoized_ivar_name} ||= {}\n if \#{memoized_ivar_name}.has_key?(all_args)\n \#{memoized_ivar_name}[all_args]\n else\n \#{memoized_ivar_name}[all_args] = \#{unmemoized_method}(*all_args)\n end\n end\n RUBY\n\n else # positive arity\n arg_names = (1..arity).map { |i| \"arg\#{i}\" }\n args_ruby = arg_names.join(', ')\n\n module_eval(<<-RUBY)\n def \#{method_name}(\#{args_ruby})\n all_args = [\#{args_ruby}]\n \#{memoized_ivar_name} ||= {}\n if \#{memoized_ivar_name}.has_key?(all_args)\n \#{memoized_ivar_name}[all_args]\n else\n \#{memoized_ivar_name}[all_args] = \#{unmemoized_method}(\#{args_ruby})\n end\n end\n RUBY\n end\n\n if self.private_method_defined?(unmemoized_method)\n private method_name\n elsif self.protected_method_defined?(unmemoized_method)\n protected method_name\n end\n end\nend\n")
|