Dependency related issues

Hey guys,

I'd like to get down to either i) fixing all the dependencies issues with the new code or ii) giving up and reverting to the old. It would really help if those of you who have had troubles could file some tickets and assign them to me. If you like, add 'dependencies' to keywords.

Thanks, Nicholas

Cool, this is the biggest issue in the core for me at the moment. Here's your first one :wink:

http://dev.rubyonrails.org/ticket/5852

For the record, Shopify works fine with the new dependency code.

I did have some issues when moving over but all those issues were pointing to errors in my code.

This isn’t exactly an issue, but a usage question for which I didn’t want to open a new topic:

With the new dependency code, what is the best way to reload plugin code on each request so we don’t have to restart the server while we’re developing/contributing to a plugin?

Thanks, -Mislav

Hello Mislav,

With the new dependency code, what is the best way to reload plugin code on each request so we don't have to restart the server while we're developing/contributing to a plugin?

At the moment plugins reload by default. However, this turns out to cause a lot of problems with some plugins. For example, if a plugin includes a module into a core class (say, AC::B) then when it is reloaded the included module will not be GC'd. It will however, be removed from the module tree.

If the included module is not overwritten by another inclusion, then we will have code that is still live, but has been removed from the module tree. This causes a fair number of issues (Such as const missing on Technoweenie from Technoweenie::Blah::SomeIncludedModule).

Because of these issues, and because they are likely to effect a large number of plugins, I'm planning to change the default so that files loaded from plugins will not be unloaded. I'll be sure to add an option to enable reloading on a plugin-by-plugin basis.

Regards, Nicholas Seckar

This would be a welcome change.

No more: rake rails:freeze:edge REVISION=4727

My biggest problem is that I often organize code into subdirectories, but don't follow the Java convention of placing that code into modules named after the subdirectories. This seems to break the autoloading.

Dave

Dave Thomas wrote:

My biggest problem is that I often organize code into subdirectories, but don't follow the Java convention of placing that code into modules named after the subdirectories.

You may call this "Java conventions" but this has also been our convention since we started loading from modules.

Without the naming conventions we have now, there's no way for dependencies to know which file to load for a given constant. Since Rails is all about conventions, I feel pretty fine in demanding a meaningful code layout.

If the conventions we've adopted chafe too much, then you're free to hack together something that will fit better. Adding qualified constant names to Dependencies.autoloaded_constants is not public API, but it's there if you want to use it.

I’ll second that. I’m running a largish application on edge that uses about 8 plugins and the only issue I had was related to the fact that Ruby libraries any no longer auto-loaded.

-Jonathan.

Hi Nicholas

Is there a strict one-file-to-one-class convention now?

Reason I ask is, I have a problem with a file (entry.rb) that defines a base class (Entry) and about 10 subclasses (ContactInfo and a bunch more).

It loads fine the first time, but when the file gets unloaded and then reloaded, I get:

entry.rb:164: superclass mismatch for class ContactInfo

Line 164 is where ContactInfo is defined, which is the first class other than Entry defined in this file. I’m guessing the error happens because Entry is now a reference to a new class, while ContactInfo still points to the old “Entry” is its parent.

Looking at the code, it does seem like it have a one-file-one-class(-with-the-same-name-as-the-file) convention built-in.

//Lars

Lars Pind wrote:

Hi Nicholas

Is there a strict one-file-to-one-class convention now?

Yea, pretty much.

Instead we could use the file's path to find the module into which it should load things (a/b/c.rb => A::B) and then get a list of constants before and after we load the file. Comparing the lists will tell us what that file loaded, and then we could mark all the constants for future removal.

This gets a little harder given that one file can load another file which may load another. PDI. :wink: