From 700c58355c04595795b03ff29e727eac7200e928 Mon Sep 17 00:00:00 2001
From: Carlos Antonio da Silva <carlosantoniodasilva@gmail.com>
Date: Thu, 26 Apr 2012 22:21:47 -0300
Subject: Improve and cleanup a bit partial renderer

* Remove template assignment: there is no need for this assignment,
  given we are rendering a collection with possibly different templates,
  and a second call to render (with the same instance) would behave
  differently if the template is set.
* Remove segments array in favor of Array#map
* Use local vars whenever possible
* Cache local template keys, remove defaults from find_template
---
 .../lib/action_view/renderer/abstract_renderer.rb  |  4 +-
 .../lib/action_view/renderer/partial_renderer.rb   | 71 +++++++++++-----------
 2 files changed, 37 insertions(+), 38 deletions(-)

(limited to 'actionpack/lib')

diff --git a/actionpack/lib/action_view/renderer/abstract_renderer.rb b/actionpack/lib/action_view/renderer/abstract_renderer.rb
index 52473cd222..72616b7463 100644
--- a/actionpack/lib/action_view/renderer/abstract_renderer.rb
+++ b/actionpack/lib/action_view/renderer/abstract_renderer.rb
@@ -14,12 +14,10 @@ module ActionView
     protected
 
     def extract_details(options)
-      details = {}
-      @lookup_context.registered_details.each do |key|
+      @lookup_context.registered_details.each_with_object({}) do |key, details|
         next unless value = options[key]
         details[key] = Array(value)
       end
-      details
     end
 
     def instrument(name, options={})
diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb
index 87609fd5ff..9100545718 100644
--- a/actionpack/lib/action_view/renderer/partial_renderer.rb
+++ b/actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -283,7 +283,7 @@ module ActionView
       return nil if @collection.blank?
 
       if @options.key?(:spacer_template)
-        spacer = find_template(@options[:spacer_template]).render(@view, @locals)
+        spacer = find_template(@options[:spacer_template], @locals.keys).render(@view, @locals)
       end
 
       result = @template ? collection_with_template : collection_without_template
@@ -291,11 +291,11 @@ module ActionView
     end
 
     def render_partial
-      locals, view, block = @locals, @view, @block
+      view, locals, block = @view, @locals, @block
       object, as = @object, @variable
 
       if !block && (layout = @options[:layout])
-        layout = find_template(layout, @locals.keys + [@variable])
+        layout = find_template(layout, @template_keys)
       end
 
       object ||= locals[as]
@@ -337,6 +337,7 @@ module ActionView
 
       if @path
         @variable, @variable_counter = retrieve_variable(@path)
+        @template_keys = retrieve_template_keys
       else
         paths.map! { |path| retrieve_variable(path).unshift(path) }
       end
@@ -358,62 +359,55 @@ module ActionView
     end
 
     def collection_from_object
-      if @object.respond_to?(:to_ary)
-        @object.to_ary
-      end
+      @object.to_ary if @object.respond_to?(:to_ary)
     end
 
     def find_partial
       if path = @path
-        locals = @locals.keys
-        locals << @variable
-        locals << @variable_counter if @collection
-        find_template(path, locals)
+        find_template(path, @template_keys)
       end
     end
 
-    def find_template(path=@path, locals=@locals.keys)
+    def find_template(path, locals)
       prefixes = path.include?(?/) ? [] : @lookup_context.prefixes
       @lookup_context.find_template(path, prefixes, true, locals, @details)
     end
 
     def collection_with_template
-      segments, locals, template = [], @locals, @template
+      view, locals, template = @view, @locals, @template
       as, counter = @variable, @variable_counter
 
       if layout = @options[:layout]
-        layout = find_template(layout, @locals.keys + [@variable, @variable_counter])
+        layout = find_template(layout, @template_keys)
       end
 
-      locals[counter] = -1
-
-      @collection.each do |object|
-        locals[counter] += 1
-        locals[as] = object
+      index = -1
+      @collection.map do |object|
+        locals[as]      = object
+        locals[counter] = (index += 1)
 
-        content = template.render(@view, locals)
-        content = layout.render(@view, locals) { content } if layout
-        segments << content
+        content = template.render(view, locals)
+        content = layout.render(view, locals) { content } if layout
+        content
       end
-
-      segments
     end
 
     def collection_without_template
-      segments, locals, collection_data = [], @locals, @collection_data
-      index, template, cache = -1, nil, {}
-      keys = @locals.keys
+      view, locals, collection_data = @view, @locals, @collection_data
+      cache = {}
+      keys  = @locals.keys
 
-      @collection.each_with_index do |object, i|
-        path, *data = collection_data[i]
-        template = (cache[path] ||= find_template(path, keys + data))
-        locals[data[0]] = object
-        locals[data[1]] = (index += 1)
-        segments << template.render(@view, locals)
-      end
+      index = -1
+      @collection.map do |object|
+        index += 1
+        path, as, counter = collection_data[index]
 
-      @template = template
-      segments
+        locals[as]      = object
+        locals[counter] = index
+
+        template = (cache[path] ||= find_template(path, keys + [as, counter]))
+        template.render(view, locals)
+      end
     end
 
     def partial_path(object = @object)
@@ -453,6 +447,13 @@ module ActionView
       end
     end
 
+    def retrieve_template_keys
+      keys = @locals.keys
+      keys << @variable
+      keys << @variable_counter if @collection
+      keys
+    end
+
     def retrieve_variable(path)
       variable = @options.fetch(:as) { path[%r'_?(\w+)(\.\w+)*$', 1] }.try(:to_sym)
       variable_counter = :"#{variable}_counter" if @collection
-- 
cgit v1.2.3