Just trying to understand the rails lifecycle
I'm exploring RouteSet to understand how / when a controller is instantiated
I was looking at this method from RouteSet:
def controller_reference(controller_param)
controller_name = "#{controller_param.camelize}Controller"
unless controller = @controllers[controller_param]
controller = @controllers[controller_param] =
ActiveSupport::Dependencies.reference(controller_name)
end
controller.get(controller_name)
end
Here's the relevent code from ActiveSupport::Dependencies
class ClassCache
def initialize
@store = Hash.new { |h, k| h[k] = Inflector.constantize(k) }
end
def empty?
@store.empty?
end
def key?(key)
@store.key?(key)
end
def []=(key, value)
return unless key.respond_to?(:name)
raise(ArgumentError, 'anonymous classes cannot be cached') if key.name.blank?
@store[key.name] = value
end
def [](key)
key = key.name if key.respond_to?(:name)
@store[key]
end
alias :get :[]
def store(name)
self[name] = name
self
end
def clear!
@store.clear
end
end
Reference = ClassCache.new
# Store a reference to a class +klass+.
def reference(klass)
Reference.store klass
end
# Get the reference for class named +name+.
def constantize(name)
Reference.get(name)
end
I dont understand is how, in the controller_reference method, the controller_name gets turned into an actual controller reference. Nor do I understand why the @controllers hash, in RouteSet, is basically caching the result of ActiveSupport::Dependancies.reference(controller_name). But isn't that always just the one reference to the ClassCache that ActiveSupport::Dependanices has? I don't get the point of caching a bunch of references to the same ActiveSupport::Dependancie's ClassCache object (Reference). Won't you just end up with a hash full of the same identical references to that ClassCache object?
Not only that but I don't understand how the ClassCache is accepting the controller_name since it's []=(key, value) , which is what the reference(klass) method is calling, returns early if key doesn't respond to name, and key in this case is just a string right? Since RouteSet only passes the name to the ActiveSupport::Dependencies.reference method.
Can anyone explain how this works? Thanks so much.