aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthedarkone <thedarkone2@gmail.com>2010-09-27 14:50:39 +0200
committerthedarkone <thedarkone2@gmail.com>2010-09-27 17:45:58 +0200
commit918dc27345319fbabf25a43bd65b613878b3a66e (patch)
tree9384f88171b155ac6655d70c2448e4e8a364fe32
parent7918a5c96604b6c2d8a60542b7afc9e445c43fba (diff)
downloadrails-918dc27345319fbabf25a43bd65b613878b3a66e.tar.gz
rails-918dc27345319fbabf25a43bd65b613878b3a66e.tar.bz2
rails-918dc27345319fbabf25a43bd65b613878b3a66e.zip
Compile ActionController::Base.config's methods to avoid method_missing overhead.
-rw-r--r--actionpack/lib/action_controller/railtie.rb10
-rw-r--r--actionpack/lib/action_view/base.rb3
-rw-r--r--activesupport/lib/active_support/configurable.rb24
-rw-r--r--activesupport/lib/active_support/ordered_options.rb4
-rw-r--r--activesupport/test/configurable_test.rb18
5 files changed, 55 insertions, 4 deletions
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index aea28d9265..4c57d82f1c 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -26,6 +26,10 @@ module ActionController
options.stylesheets_dir ||= paths.public.stylesheets.to_a.first
options.page_cache_directory ||= paths.public.to_a.first
+ # make sure readers methods get compiled
+ options.asset_path ||= nil
+ options.asset_host ||= nil
+
ActiveSupport.on_load(:action_controller) do
include app.routes.mounted_helpers
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
@@ -33,5 +37,11 @@ module ActionController
options.each { |k,v| send("#{k}=", v) }
end
end
+
+ config.after_initialize do
+ ActiveSupport.on_load(:action_controller) do
+ config.crystalize! if config.respond_to?(:crystalize!)
+ end
+ end
end
end
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 3fa46d0f43..0bef3e3a08 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -209,8 +209,7 @@ module ActionView #:nodoc:
@_request = controller.request if controller.respond_to?(:request)
end
- config = controller && controller.respond_to?(:config) ? controller.config : {}
- @_config = ActiveSupport::InheritableOptions.new(config)
+ @_config = controller && controller.respond_to?(:config) ? controller.config.inheritable_copy : {}
@_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
@_virtual_path = nil
diff --git a/activesupport/lib/active_support/configurable.rb b/activesupport/lib/active_support/configurable.rb
index 5b85f9394a..36634bd7f3 100644
--- a/activesupport/lib/active_support/configurable.rb
+++ b/activesupport/lib/active_support/configurable.rb
@@ -9,9 +9,29 @@ module ActiveSupport
module Configurable
extend ActiveSupport::Concern
+ class Configuration < ActiveSupport::InheritableOptions
+ def crystalize!
+ self.class.crystalize!(keys.reject {|key| respond_to?(key)})
+ end
+
+ # compiles reader methods so we don't have to go through method_missing
+ def self.crystalize!(keys)
+ keys.each do |key|
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
+ def #{key}; self[#{key.inspect}]; end
+ RUBY
+ end
+ end
+ end
+
module ClassMethods
def config
- @_config ||= ActiveSupport::InheritableOptions.new(superclass.respond_to?(:config) ? superclass.config : {})
+ @_config ||= if superclass.respond_to?(:config)
+ superclass.config.inheritable_copy
+ else
+ # create a new "anonymous" class that will host the compiled reader methods
+ Class.new(Configuration).new({})
+ end
end
def configure
@@ -48,7 +68,7 @@ module ActiveSupport
# user.config.level # => 1
#
def config
- @_config ||= ActiveSupport::InheritableOptions.new(self.class.config)
+ @_config ||= self.class.config.inheritable_copy
end
end
end
diff --git a/activesupport/lib/active_support/ordered_options.rb b/activesupport/lib/active_support/ordered_options.rb
index 37e357552c..2b67e72cff 100644
--- a/activesupport/lib/active_support/ordered_options.rb
+++ b/activesupport/lib/active_support/ordered_options.rb
@@ -39,5 +39,9 @@ module ActiveSupport #:nodoc:
def initialize(parent)
super() { |h,k| parent[k] }
end
+
+ def inheritable_copy
+ self.class.new(self)
+ end
end
end
diff --git a/activesupport/test/configurable_test.rb b/activesupport/test/configurable_test.rb
index cef67e3cf9..4f288eb4d5 100644
--- a/activesupport/test/configurable_test.rb
+++ b/activesupport/test/configurable_test.rb
@@ -39,4 +39,22 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase
assert_equal :baz, instance.config.foo
assert_equal :bar, Parent.config.foo
end
+
+ test "configuration is crystalizeable" do
+ parent = Class.new { include ActiveSupport::Configurable }
+ child = Class.new(parent)
+
+ parent.config.bar = :foo
+ assert !parent.config.respond_to?(:bar)
+ assert !child.config.respond_to?(:bar)
+ assert !child.new.config.respond_to?(:bar)
+
+ parent.config.crystalize!
+ assert_equal :foo, parent.config.bar
+ assert_equal :foo, child.new.config.bar
+
+ assert_respond_to parent.config, :bar
+ assert_respond_to child.config, :bar
+ assert_respond_to child.new.config, :bar
+ end
end \ No newline at end of file