From 1f5b9bbdb377c1b0e29650a103bf53526ceefdd5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?= <jose.valim@gmail.com>
Date: Tue, 13 Dec 2011 10:07:02 +0100
Subject: Clean up FileUpdateChecker API.

---
 .../lib/active_support/file_update_checker.rb      | 25 +++++++++++-----------
 activesupport/lib/active_support/i18n_railtie.rb   |  8 +++++--
 activesupport/test/file_update_checker_test.rb     |  2 +-
 railties/lib/rails/application/finisher.rb         |  2 +-
 railties/lib/rails/application/routes_reloader.rb  |  8 +++----
 5 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/activesupport/lib/active_support/file_update_checker.rb b/activesupport/lib/active_support/file_update_checker.rb
index 4137bbf6a0..3028fbdd00 100644
--- a/activesupport/lib/active_support/file_update_checker.rb
+++ b/activesupport/lib/active_support/file_update_checker.rb
@@ -16,8 +16,6 @@ module ActiveSupport
   #   end
   #
   class FileUpdateChecker
-    attr_reader :paths, :last_update_at
-
     # It accepts two parameters on initialization. The first is
     # the *paths* and the second is *calculate*, a boolean.
     #
@@ -29,12 +27,13 @@ module ActiveSupport
     # on initialization, therefore, the first call to execute_if_updated
     # will only evaluate the block if something really changed.
     #
-    # This method must also receive a block that will be the block called
-    # once a file changes.
+    # This method must also receive a block that will be called once a file changes.
     #
     # This particular implementation checks for added files and updated files,
     # but not removed files. Directories lookup are compiled to a glob for
-    # performance.
+    # performance. Therefore, while someone can add new files to paths after
+    # initialization, adding new directories is not allowed. Notice that,
+    # depending on the implementation, not even new files may be added.
     def initialize(paths, calculate=false, &block)
       @paths = paths
       @glob  = compile_glob(@paths.extract_options!)
@@ -44,7 +43,7 @@ module ActiveSupport
     end
 
     # Check if any of the entries were updated. If so, the updated_at
-    # value is cached until flush! is called.
+    # value is cached until the block is executed via +execute+ or +execute_if_updated+
     def updated?
       current_updated_at = updated_at
       if @last_update_at != current_updated_at
@@ -55,8 +54,11 @@ module ActiveSupport
       end
     end
 
-    # Flush the cache so updated? is calculated again
-    def flush!
+    # Executes the given block expiring any internal cache.
+    def execute
+      @last_update_at = updated_at
+      @block.call
+    ensure
       @updated_at = nil
     end
 
@@ -64,14 +66,11 @@ module ActiveSupport
     # always flush the cache.
     def execute_if_updated
       if updated?
-        @last_update_at = updated_at
-        @block.call
+        execute
         true
       else
         false
       end
-    ensure
-      flush!
     end
 
     private
@@ -86,7 +85,9 @@ module ActiveSupport
     end
 
     def compile_glob(hash) #:nodoc:
+      hash.freeze # Freeze so changes aren't accidently pushed
       return if hash.empty?
+
       globs = []
       hash.each do |key, value|
         globs << "#{key}/**/*#{compile_ext(value)}"
diff --git a/activesupport/lib/active_support/i18n_railtie.rb b/activesupport/lib/active_support/i18n_railtie.rb
index a989ff8f57..ae3a39562c 100644
--- a/activesupport/lib/active_support/i18n_railtie.rb
+++ b/activesupport/lib/active_support/i18n_railtie.rb
@@ -10,7 +10,11 @@ module I18n
     config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
 
     def self.reloader
-      @reloader ||= ActiveSupport::FileUpdateChecker.new([]){ I18n.reload! }
+      @reloader ||= ActiveSupport::FileUpdateChecker.new(reloader_paths){ I18n.reload! }
+    end
+
+    def self.reloader_paths
+      @reloader_paths ||= []
     end
 
     # Add <tt>I18n::Railtie.reloader</tt> to ActionDispatch callbacks. Since, at this
@@ -59,7 +63,7 @@ module I18n
 
       init_fallbacks(fallbacks) if fallbacks && validate_fallbacks(fallbacks)
 
-      reloader.paths.concat I18n.load_path
+      reloader_paths.concat I18n.load_path
       reloader.execute_if_updated
 
       @i18n_inited = true
diff --git a/activesupport/test/file_update_checker_test.rb b/activesupport/test/file_update_checker_test.rb
index 52c1f3260d..c54ba427fa 100644
--- a/activesupport/test/file_update_checker_test.rb
+++ b/activesupport/test/file_update_checker_test.rb
@@ -63,7 +63,7 @@ class FileUpdateCheckerWithEnumerableTest < Test::Unit::TestCase
     FileUtils.touch(FILES)
 
     assert checker.updated?
-    assert checker.execute_if_updated
+    checker.execute
     assert !checker.updated?
   end
 
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index 738fb93994..064723c1e0 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -83,7 +83,7 @@ module Rails
           self.reloaders << reloader
           # We need to set a to_prepare callback regardless of the reloader result, i.e.
           # models should be reloaded if any of the reloaders (i18n, routes) were updated.
-          ActionDispatch::Reloader.to_prepare(:prepend => true, &callback)
+          ActionDispatch::Reloader.to_prepare(:prepend => true){ reloader.execute }
         else
           ActionDispatch::Reloader.to_cleanup(&callback)
         end
diff --git a/railties/lib/rails/application/routes_reloader.rb b/railties/lib/rails/application/routes_reloader.rb
index 460b84dfd9..e080481976 100644
--- a/railties/lib/rails/application/routes_reloader.rb
+++ b/railties/lib/rails/application/routes_reloader.rb
@@ -3,12 +3,12 @@ require "active_support/core_ext/module/delegation"
 module Rails
   class Application
     class RoutesReloader
-      attr_reader :route_sets
-
-      delegate :paths, :execute_if_updated, :updated?, :to => :@updater
+      attr_reader :route_sets, :paths
+      delegate :execute_if_updated, :updated?, :to => :@updater
 
       def initialize(updater=ActiveSupport::FileUpdateChecker)
-        @updater    = updater.new([]) { reload! }
+        @paths      = []
+        @updater    = updater.new(paths) { reload! }
         @route_sets = []
       end
 
-- 
cgit v1.2.3