Is there a way to find out which (gem) plugins are loaded without repeating work the initializer has already done?
Michael
Is there a way to find out which (gem) plugins are loaded without repeating work the initializer has already done?
Michael
The problem is that the current Initializer instance isn’t saved anywhere.
If you change your environment.rb like this:
Init = Rails::Initializer.run …
Then you can read from it later:
Init.loaded_plugins.map &:name
That's not what I want, although I deliberately didn't say what I'm trying to do. I'm currently hacking on the rails/info controller to make it modular. I'd like to add a hook for plugins/gems as well as the application to add their own diagnostic information to that controller.
There are, of course, several packages for introspecting a rails app already, but I think there is room for a simple, very lightweight standard hook for extensions to add information. Particularly, a hook that is always available, not dependent on additional extensions.
Michael
For gems, your best bet is to iterate over Gem.loaded_specs. That
should return everything that's been loaded. You'll need to look for a
rails/init.rb file to tell if it's a plugin.
--Matt Jones
No, but it's been proposed: https://rails.lighthouseapp.com/projects/8994/tickets/2526
jeremy
As I've been hacking around in Railties anyway, I've changed to code to my liking and moved loaded_plugins from Initializer to Configuration.
Michael
I think that your goal, “get a list of loaded plugins”, is fairly straightforward and I don’t understand why we need to know what are you going to do with it. What I’m interested in is why do you think saving the Initializer instance isn’t adequate?
Rails saves the active Configuration instance, so for consistency it should also save the Initializer. After 2 additional lines of code we could access plugins like:
Rails.initializer.loaded_plugins
Because that's something the application programmer would have to do. I was working inside of railties. See the parallel thread on /rails/info/properties I just started.
Michael
I've done a little bit of thinking around this, and my preference would be, roughly in order:
1) Rails.loaded_plugins 2) Rails.configuration.loaded_plugins 3) Rails.initializer.loaded_plugins
Ideally (and I think Yehuda touched on this slightly at RailsConf) I feel there ought to be an instance which represents a booted Rails application, which should know about which plugins have been loaded. Then I'd hope have a method along the lines of Rails::App#plugins (the 'loaded' part is implied), or whatever.
Since no such object currently exists, accessing the set of currently & successfully loaded plugins directly from the Rails constant seems most consistent (i.e. along with Rails.root as the directory of the currently running app, and Rails.configuration as the configuration specification that was used during the boot of the currently running app).
Rails.configuration.loaded_plugins seems relatively less-good because, IMHO, the configuration object is more about specification than state. It's where I tell Rails which plugins/gems to load, not the object which actually has any responsibility for loading them. It seems like having an object designed to describe database connection parameters, and then deciding to store the actual connection instance in that object too; not the most elegant design.
Rails.initializer.loaded_plugins is my "least favourite" because it exposes the fact that Rails has an initializer, which I shouldn't really need to care about; it's exposing an implementation detail (plugins get loaded via some Initializer class), rather than providing a clean and sensible API for finding out which plugins have loaded.
All this said, I do realise that the distinctions are incredibly (and some might say pointlessly) subtle, and may be meaningless to everyone bar me. Most importantly,and why I said 'least favourite' above, *any* implementation would be better than none.
James
My patch at
https://rails.lighthouseapp.com/projects/8994/tickets/2684-modular- rails-info
currently does 2). However, I agree with your argument and will change it to 1).
Michael