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.
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?
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.
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.
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.
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.
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.