Skip to content

Commit 5c747d0

Browse files
committed
Define method using class_eval instead of define_method.
1 parent cea163c commit 5c747d0

2 files changed

Lines changed: 31 additions & 10 deletions

File tree

lib/simple_json/simple_json_renderer.rb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ def load_template_from_file(template_path)
3939
SimpleJson.template_paths.each do |path|
4040
file_path = Rails.root.join("#{path}/#{template_path}.simple_json.rb").to_path
4141

42-
if File.exist?(file_path)
43-
return define_template_method(template_path, file_path)
44-
end
42+
return define_template_method(template_path, file_path) if File.exist?(file_path)
4543
end
4644

4745
nil
@@ -52,9 +50,7 @@ def define_template_method(template_path, file_path)
5250
@template_num += 1
5351
method_name = :"template_#{@template_num}"
5452
render_methods[template_path] = method_name
55-
define_method(method_name, &SimpleJsonTemplate.new(file_path).lambda)
56-
57-
return method_name
53+
SimpleJsonTemplate.new(file_path).define_to_class(self, method_name)
5854
end
5955

6056
def render_methods

lib/simple_json/simple_json_template.rb

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,45 @@ def initialize(path)
77
@source = File.read(path)
88
end
99

10-
def lambda
11-
@lambda ||= eval(code, TOPLEVEL_BINDING, @path) # rubocop:disable Security/Eval
10+
def define_to_class(klass, method_name)
11+
method_string = to_method_string(method_name)
12+
klass.class_eval(method_string, @path)
13+
14+
method_name
1215
end
1316

17+
private
18+
1419
def code
1520
@code ||= lambda_stringify(@source)
1621
end
1722

18-
private
19-
2023
def lambda_stringify(source)
2124
return source if source.match?(/^(?:\s*(?:#.*?)?\n)*\s*->/)
2225

2326
"-> { #{source} }"
2427
end
28+
29+
def method_string_from_lambda(source, method_name)
30+
pattern = %r{
31+
\A(?<prefix>(?:\s*#.*\n|\s+)*)
32+
->\s*
33+
(?:\((?<params_p>.*?)\)|(?<params_n>[^{ ]*?))
34+
\s*(?:\{(?<body>.*)\}|do(?<body>.*)end)
35+
(?<suffix>(?:\s*#.*|\s+)*)\z
36+
}mx
37+
38+
match = source.match(pattern)
39+
raise :parse_error unless match
40+
41+
params = (match[:params_p] || match[:params_n] || "").strip
42+
arg_part = params.empty? ? "" : "(#{params})"
43+
44+
"#{match[:prefix]}def #{method_name}#{arg_part};#{match[:body]};end#{match[:suffix]}"
45+
end
46+
47+
def to_method_string(method_name)
48+
method_string_from_lambda(code, method_name)
49+
end
2550
end
2651
end

0 commit comments

Comments
 (0)