aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/lookup_context.rb
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-03-27 20:51:25 +0100
committerJosé Valim <jose.valim@gmail.com>2010-03-27 20:52:11 +0100
commita09e99259c688a839bd5b4635da6f119dd1e0e41 (patch)
tree9e1399562185082853aacc837211f837f7a5a231 /actionpack/lib/action_view/lookup_context.rb
parentfdebc7f55bdd9730216ac1f00880838ae0db90bd (diff)
downloadrails-a09e99259c688a839bd5b4635da6f119dd1e0e41.tar.gz
rails-a09e99259c688a839bd5b4635da6f119dd1e0e41.tar.bz2
rails-a09e99259c688a839bd5b4635da6f119dd1e0e41.zip
Ensure details are frozen after @details_keys lookup. The implementation waits to freeze until the last required moment, to avoid duping hashes.
Diffstat (limited to 'actionpack/lib/action_view/lookup_context.rb')
-rw-r--r--actionpack/lib/action_view/lookup_context.rb21
1 files changed, 17 insertions, 4 deletions
diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb
index 10f1911e31..9b59aac0eb 100644
--- a/actionpack/lib/action_view/lookup_context.rb
+++ b/actionpack/lib/action_view/lookup_context.rb
@@ -23,9 +23,12 @@ module ActionView
def #{name}=(value)
value = Array.wrap(value.presence || _#{name}_defaults)
- @details_key = nil unless value == @details[:#{name}]
- # Always set the value to handle frozen arrays
- @details[:#{name}] = value
+
+ if value != @details[:#{name}]
+ @details_key = nil
+ @details = @details.dup if @details.frozen?
+ @details[:#{name}] = value.freeze
+ end
end
METHOD
end
@@ -45,7 +48,7 @@ module ActionView
@details_keys = Hash.new
def self.get(details)
- @details_keys[details] ||= new
+ @details_keys[details.freeze] ||= new
end
def initialize
@@ -55,6 +58,7 @@ module ActionView
def initialize(view_paths, details = {})
@details, @details_key = { :handlers => default_handlers }, nil
+ @frozen_formats = false
self.view_paths = view_paths
self.update_details(details, true)
end
@@ -127,6 +131,15 @@ module ActionView
@details_key ||= DetailsKey.get(@details)
end
+ # Freeze the current formats in the lookup context. By freezing them, you are guaranteeing
+ # that next template lookups are not going to modify the formats. The controller can also
+ # use this, to ensure that formats won't be further modified (as it does in respond_to blocks).
+ def freeze_formats(formats, unless_frozen=false) #:nodoc:
+ return if unless_frozen && @frozen_formats
+ self.formats = formats
+ @frozen_formats = true
+ end
+
# Overload formats= to reject [:"*/*"] values.
def formats=(value)
value = nil if value == [:"*/*"]