提交 918dc273 编写于 作者: T thedarkone

Compile ActionController::Base.config's methods to avoid method_missing overhead.

上级 7918a5c9
......@@ -26,6 +26,10 @@ class Railtie < Rails::Railtie
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 @@ class Railtie < Rails::Railtie
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
......@@ -209,8 +209,7 @@ def initialize(lookup_context = nil, assigns_for_first_render = {}, controller =
@_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
......
......@@ -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 @@ def #{name}=(value); config.#{name} = value; end
# user.config.level # => 1
#
def config
@_config ||= ActiveSupport::InheritableOptions.new(self.class.config)
@_config ||= self.class.config.inheritable_copy
end
end
end
......
......@@ -39,5 +39,9 @@ class InheritableOptions < OrderedOptions
def initialize(parent)
super() { |h,k| parent[k] }
end
def inheritable_copy
self.class.new(self)
end
end
end
......@@ -39,4 +39,22 @@ class Child < Parent
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册