Plugin load paths & load order

Messing around with the plugin loading mechanism (as I love to do), I stumbled on a $LOAD_PATH oddity and I was wondering if I'm missing the reasoning behind it. At the moment, plugin lib directories are added to the $LOAD_PATH by two independent mechanisms:

    * Rails::Initializer#load_plugins adds them when the plugin is loaded     * Rails::Initializer::Configuration#default_load_paths includes them by default

This behaviour seems broken in the light of the config.plugins; if I have chosen to control the plugins I need to load, other plugin lib directories simply shouldn't be available to Rails.

If there's a reason for this, I'd love to know; alternatively, there's a tiny patch here: http://dev.rubyonrails.org/ticket/6842

Also, while I've got your attention, I noticed a while back that Koz suggested that plugin load order could be controlled by config.plugins:

  "The recent addition of config.plugins will let you specify which plugins to load, and which order to load them in." (http://dev.rubyonrails.org/ticket/6418)

This, alas, isn't the case. Is there any support for having Rails respect the order that plugins are specified in on config.plugins? Rather than being anything approaching "plugin dependencies" (spit, gag, splutter), this just adds a bit more meaning to an existing configuration option....

Also reported here: http://dev.rubyonrails.org/ticket/6571

James Adam wrote:

  "The recent addition of config.plugins will let you specify which plugins to load, and which order to load them in." (http://dev.rubyonrails.org/ticket/6418)

config.plugins prevents the init.rb from being called, meaning the plugins 'lie dormant'. What's the scenario we're trying to prevent by stopping them from appearing on the load paths?

Having said that, a patch to tidy all that up, and make config.plugins a little more powerful does seem reasonable.

> "The recent addition of config.plugins will let you specify which > plugins to load, and which order to load them in." > (http://dev.rubyonrails.org/ticket/6418)

config.plugins prevents the init.rb from being called, meaning the plugins 'lie dormant'. What's the scenario we're trying to prevent by stopping them from appearing on the load paths?

The issue would be where a 'disabled' plugin contains a class with the same name as something lower down in the load path, i.e. a plugin with the file 'struct.rb' will always be loaded rather than one from the Ruby lib paths (which are by default at the end of the load path).

I think it's fairly unlikely that something like this would come up in practice, but it's worth cleaning the load path just for the sake of being a good citizen, and if Rails suggests that you can disable a plugin by not including it in config.plugins, it really should ensure that the plugin has no affect on the running application unless it is enabled.

Having said that, a patch to tidy all that up, and make config.plugins a little more powerful does seem reasonable.

More than happy to do this. Obrie marked my original patch as a duplicate to his own, although I'm not sure that they have the same effect - it depends on when $LOAD_PATH.uniq! is called, and the behaviour of Array#uniq!; while at the moment both patches are effective, I think it's just clearer to have a single point where plugin lib directories are dealt with, and that should be in load_plugin().

I'll repost to this thread with a patch making config.plugins a little more powerful soon.

Cheers!

As promised: http://dev.rubyonrails.org/ticket/6851

Is there *any* chance that this change might be included in 1.2?.... *grovels* :wink:

I've left out the changes to ensure that plugin lib directories only appear in the $LOAD_PATH once; I'd suggest you choose from

* http://dev.rubyonrails.org/ticket/6842 - remove plugins from the default_load_paths * http://dev.rubyonrails.org/ticket/6571 - add a trailing slash when loading plugins and then use $LOAD_PATH.uniq! to clear out duplicates

... they're both tiny & clean patches that should do the job. IMHO #6842 is a cleaner and 'more correct' way to resolve the duplication, but either way the duplicates are cleared.

Cheers guys,

I agree with James. I'm not really sure why it was added there in the first place (plus it's really not correct either since it doesn't add plugins in subdirectories). So with his solution, we get fix 2 problems with 1 stone.

James Adam wrote:

It occurred to me on the walk home that our two patches solve slightly different problems; adding the trailing slash to paths added by load_plugin won't prevent all plugin lib directories being added to the $LOAD_PATH, it will only prevent duplicates. My original query was with why all the plugin libr directories were being added regardless of the contents of config.plugins...

But anyway, I've rolled in your 'trailing-slash' fix into the patch on Ticket #6842, so that should kill every bird with one tiny pebble :slight_smile:

No brainer patch to apply: http://dev.rubyonrails.org/ticket/6842

Cheers

No brainer patch to apply: http://dev.rubyonrails.org/ticket/6842

Applied this and 6851 to trunk and 1.2. Thanks!

Hey guys, I thought we were all ready for a new Rails 1.2 RC, but I just realized I had cache_classes=true in one of my apps, and it started bombing as soon as I changed it back. So here's the changeset: http://dev.rubyonrails.org/changeset/5801

Nicholas' load_once_path changes were working, but none of the plugin paths were ever being added to it. #default_load_once_paths in Rails::Initializer wasn't working because it runs before plugins are initialized (and plugin lib paths aren't in default_load_paths). So, I just forced an addition to Dependencies.load_once_paths in #load_plugin.

This change seems to work, but it makes it so no plugins reload at all (which has been the current behavior of plugins since the beginning). However, if you do want your plugins to reload, you can just add this to the top of init.rb:

Dependencies.load_once_paths.delete(lib_path)

Any problems with this approach? I just don't think all these plugins have been written to deal with reloading, so I don't want to force folks to restructure them. Maybe this can be changed for Rails 2.0 though...

Sounds good to me Rick.