--20cf300e4bf3338ac604b1a59c9c Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable We don't use autoload for one simple reason: we support nested autoloads and don't know ahead of time whether an intermediate module is a module or class. Consider the following file structure: |-app | |-models | | |-admin | | | |-user.rb At various times, I have tried to have Rails' internal structure operate by setting up autoloads ahead of time and letting Ruby do the rest. Unfortunately, in this case, we would have to explicitly define Admin, but we have no way to know whether Admin is a module or class. If we define it as a module, for instance, and user.rb looks like this: class Admin class User < ActiveRecord::Base end end we get: "Admin is not a class". As a result, cannot set everything up ahead of time and have to let the first file that is autoloaded define the intermediate namespaces. --- ASIDE --- While we're on the topic, http://redmine.ruby-lang.org/issues/2740 is probably the major remaining issue with Rails' autoload solution. To summarize: module Foo def self.const_missing(id) return lookup(id) if can_lookup?(id) raise NoConstantError end module Bar def self.const_missing(id) return lookup(id) if can_lookup?(id) raise NoConstantError end end end The reason this is needed is that this: module Foo module Bar Baz end end has different semantics than: module Foo::Bar Baz end Rails can't tell the difference between these two cases, and therefore guesses that it's *probably* the first case. But consider this situation: # foo/array.rb module Foo class Array end end module Foo::Bar Array end Because we can't tell from the const_missing call that the nesting is [Foo::Bar], we assume it's [Foo::Bar, Foo] and load in foo/array.rb even though that is not the semantically correct behavior. In 99% of cases, this does not cause any problems, but when it fails (for this and other reasons), it causes pretty extreme confusion. Yehuda Katz (ph) 718.877.1325 On Sun, Nov 13, 2011 at 8:00 AM, Aaron Patterson <tenderlove / ruby-lang.org>wrote: > On Sun, Nov 13, 2011 at 10:35:42AM +0900, Hiroshi Nakamura wrote: > > -----BEGIN PGP SIGNED MESSAGE----- > > Hash: SHA1 > > > > (2011/11/13 1:58), Mike Perham wrote: > > > My use case: I want to use Rails in thread-safe mode in production > > > so I don't have to fork 20 Ruby processes to handle 20 concurrent > > > requests. When developing, Rails auto loads classes on every > > > request. This auto loading is critical to Rails' rapid development > > > cycle and there's no way I'm going to disable it. Unfortunately > > > the current autoload behavior makes the development environment > > > incompatible with thread-safe mode. > > > > I should read ActiveSupport source code first but please allow me to > > post lazy question. Does Rails development mode use autoload? It is > > doing constant lookup by itself I guess, but I could be wrong, of course. > > ActiveSupport doesn't use autoload for loading missing constants, but > supporting libraries definitely use autoloading things. It's quite > possible that files loaded using the missing constant hooks contain > autoload directives. :( > > -- > Aaron Patterson > http://tenderlovemaking.com/ > --20cf300e4bf3338ac604b1a59c9c Content-Type: text/html; charset=windows-1252 Content-Transfer-Encoding: quoted-printable <div>We don't use autoload for one simple reason: we support nested autoloads and don't know ahead of time whether an intermediate module is aodule or class. Consider the following file structure:</div><div><br></div> <div>|-app</div><div>| |-models</div><div>| | |-admin</div><div>| | | |-user.rb</div><div><br></div><div>At various times, I have tried to have Rails' internal structure operate by setting up autoloads ahead of time and letting Ruby do the rest. Unfortunately, in this case, we would have to explicitly define Admin, but we have no way to know whether Admin is a module or class. If we define it as a module, for instance, and user.rb looks like this:</div> <div><br></div><div>class Admin</div><div>class User < ActiveRecord::Base</div><div>/div><div>end</div><div>end</div><div><br></div><div>we get: "Admin is not a class". As a result, cannot setverything up ahead of time and have to let the first file that is autoloaded define the intermediate namespaces.</div> <div><br></div><div>--- ASIDE ---</div><div><br></div><div>While we're on the topic,a href="http://redmine.ruby-lang.org/issues/2740">http://redmine.ruby-lang.org/issues/2740</a> ¨Âðòïâáâìù ôèíáêïòåíáéîéîéóóõ÷éôè Òáéì󦣳¹» áõôïìïáä óïìõôéïîÔï óõííáòéú庼¯äéö¾ <div><br></div><div>module Foo</div><div>def self.const_missing(id)</div><div>return lookup(id) if can_lookup?(id)</div><div>raiseoConstantError</div><div>end</div><div><br></div><div>module Bar</div><div> <div>def self.const_missing(id)</div><div>return lookup(id) if can_lookup?(id)</div><div>raise NoConstantError</div><div>end</div></div><div>end</div><div>end</div><div><br></div><div>The reason this is needed is that this:</div> <div><br></div><div>module Foo</div><div>module Bar</div><div>Baz</div><div>end</div><div>end</div><div><br></div><div>has different semantics than:</div><div><br></div><div>module Foo::Bar</div><div>Baz</div><div> end</div><div><br></div><div>Rails can't tell the difference between these two cases, and therefore guesses that it's *probably* the first case. But consider this situation:</div><div><br></div><div># foo/array.rb</div> <div>module Foo</div><div>class Array</div><div>end</div><div>end</div><div><br></div><div>module Foo::Bar</div><div>Array</div><div>end</div><div><br></div><div>Because we can't tell from the const_missing call that the nesting is [Foo::Bar], we assume it's [Foo::Bar, Foo] and load in foo/array.rb even though that is not the semantically correct behavior. In 99% of cases, this does not cause any problems, but when it fails (for this and other reasons), it causes pretty extreme confusion.</div> <br clear="all">Yehuda Katz<br>(ph) 718.877.1325<br> <br><br><div class="gmail_quote">On Sun, Nov 13, 2011 at 8:00 AM, Aaron Patterson <span dir="ltr"><tenderlove / ruby-lang.org></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> <div class="im">On Sun, Nov 13, 2011 at 10:35:42AM +0900, Hiroshi Nakamura wrote:<br> > -----BEGIN PGP SIGNED MESSAGE-----<br> > Hash: SHA1<br> ><br> > (2011/11/13 1:58), Mike Perham wrote:<br> > > My use case: I want to use Rails in thread-safe mode in production<br> > > so I don't have to fork 20 Ruby processes to handle 20 concurrent<br> > > requests. ¨ÂèåäåöåìïðéîçÒáéìáõôï ìïáäãìáóóåïî åöåòù¼âò> > request. ¨Âèéáõôï ìïáäéîéó ãòéôéãáì ôï Òáéì󦣳¹» òáðéäåöåìïðíåîô¼âò> > cycle and there's no way I'm going to disable it. ¨Âîæïòôõîáôåìù¼âò¾ > > the current autoload behavior makes the development environment<br> > > incompatible with thread-safe mode.<br> ><br> > I should read ActiveSupport source code first but please allow me to<br> > post lazy question. ¨ÂïåÒáéìäåöåìïðíåîíïäå õóáõôïìïáä ¨Âôó¼âò¾ > doing constant lookup by itself I guess, but I could be wrong, of course.<br> <br> </div>ActiveSupport doesn't use autoload for loading missing constants,ut<br> supporting libraries definitely use autoloading things. ¨Âô¦£³¹»ñõéôå¼âòpossible that files loaded using the missing constant hooks contain<br> autoload directives. (<br> <span class="HOEnZb"><font color="#888888"><br> --<br> Aaron Patterson<br> <a href="http://tenderlovemaking.com/" target="_blank">http://tenderlovemaking.com/</a><br> </font></span></blockquote></div><br> --20cf300e4bf3338ac604b1a59c9c--