Skip to content

Commit 7656143

Browse files
committed
Normalize locals in unbound templates
1 parent da81403 commit 7656143

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

actionview/lib/action_view/unbound_template.rb

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,25 @@ def initialize(source, identifier, details:, virtual_path:)
1414
@virtual_path = virtual_path
1515

1616
@templates = Concurrent::Map.new(initial_capacity: 2)
17+
@write_lock = Mutex.new
1718
end
1819

1920
def bind_locals(locals)
20-
@templates[locals] ||= build_template(locals)
21+
if template = @templates[locals]
22+
template
23+
else
24+
@write_lock.synchronize do
25+
normalized_locals = normalize_locals(locals)
26+
27+
# We need ||=, both to dedup on the normalized locals and to check
28+
# while holding the lock.
29+
@templates[normalized_locals] ||= build_template(normalized_locals)
30+
31+
# This may have already been assigned, but we've already de-dup'd so
32+
# reassignment is fine.
33+
@templates[locals.dup] = @templates[normalized_locals]
34+
end
35+
end
2136
end
2237

2338
private
@@ -31,8 +46,12 @@ def build_template(locals)
3146
variant: variant&.to_s,
3247
virtual_path: @virtual_path,
3348

34-
locals: locals
49+
locals: locals.map(&:to_s)
3550
)
3651
end
52+
53+
def normalize_locals(locals)
54+
locals.map(&:to_sym).sort!.freeze
55+
end
3756
end
3857
end

0 commit comments

Comments
 (0)