Skip to content

Instantly share code, notes, and snippets.

@jakerr
Created October 22, 2011 23:51
Show Gist options
  • Save jakerr/1306642 to your computer and use it in GitHub Desktop.
Save jakerr/1306642 to your computer and use it in GitHub Desktop.
Trying to understand Rails lifecycle

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment