

Rails autoloading – how it works and when it doesn't - urbanautomaton
http://urbanautomaton.com/blog/2013/08/27/rails-autoloading-hell/

======
jrochkind1
While designed to make things easier for newcomers -- I think these features
are actually some of the biggest culprits in making things _harder_ for
newcomers, because they fail at so many edges, and when they do fail, there's
so much magic going on that it's nearly impossible for a newcomer (or even an
intermediate user!) to figure out what's going on and why.

I think the heavy emphasis on auto-loading was a mistake, that someone writing
a new framework would be wise to learn from and not repeat.

The reloading in dev mode is HUGELY convenient, I have to admit so I have
trouble calling it a mistake -- but is also a huge mess when it fails, and
does not work under multi-threaded request dispatch. That latter will, I
think, become an increasing problem as more people use multi-threaded request
dispatch in Rails -- Rails4 has multi-threaded request dispatch on by defualt
in production mode. But I think _not_ in development mode, precisely because
of the code-reloading problem. But I'm not sure diverging the dev and
production environments (violating 12-factor, incidentally) is a good
sustainable solution.

~~~
urbanautomaton
I totally agree. And this is before we even consider what ubiquitous
autoloading encourages us to do to our code in terms of coupling. Our classes
are available everywhere, so the tendency to create many hard dependencies on
a wide range of classes is very strong. Want to run a SQL query right in a
view? Nothing stopping you. Want to instantiate a controller in a model so you
can get at the path helpers? I will hunt you-- er, sorry, I mean, "nothing
stopping you" (except your pride).

Like you, I find it very hard to rubbish the auto-reloading, but even this
encourages bad habits, I think. Rather than write tests for the behaviour we
just implemented, or the bug we just fixed, we hit F5. Didn't work? Change
something, hit F5. This at least isn't really Rails' fault; it's our job as
programmers to do the professional thing. But it does act as something of a
siren call to the rocks of cowboy programming. And like you say, there are
other, more insidious issues with divergent dev/production environments.

------
pothibo
Actually, rails overloads Ruby's autoload. So they do share some behavior.
What rails does is it lets you only provide a module name and rails will try
to find the path for you.

Also, the class reloading is done through ActionDispatch::Reloader. Those are
middlewares (There's 3 of them by default IIRC).

I wrote about how it works and how you can use that to customize some of your
code inside the app/ folder.

Shameless plug: [http://pothibo.com/2013/07/namespace-stuff-in-your-app-
folde...](http://pothibo.com/2013/07/namespace-stuff-in-your-app-folder/)

~~~
urbanautomaton
Rails does overload Ruby's autoload (naturally - no core functionality can
remain un-monkeypatched. ;-)), but not for the on-demand autoloading the
article describes, which is what most users contend with most frequently, and
was what I most wanted to demystify. Thanks for the clarification though -
I'll try to make the distinction clearer.

~~~
pothibo
>>Rails does overload Ruby's autoload (naturally - no core functionality can
remain un-monkeypatched. ;-))

Are you sure about that? To me it seems that if you pass a path to autoload,
it does work like ruby STL
[https://github.com/rails/rails/blob/master/activesupport/lib...](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/dependencies/autoload.rb#L35)

~~~
urbanautomaton
Yep - if you pass a path the behaviour is as normal, but it's still overloaded
to support the path inference behaviour. I guess it's not really
monkeypatching though as `Module` itself is not modified, and you have to
deliberately choose to use `ActiveSupport::Autoload`, so I reluctantly retract
my parenthetical snark. :-)

------
excepttheweasel
"Perhaps, because we always had autoloading as a crutch, our existing
knowledge has atrophied – or never even developed – putting us at an even
greater disadvantage."

I think the same can be said of any abstraction. The Ruby programming language
as an abstraction over C. C as an abstraction over assembler. etc. Yet few
people write code in assembler. I don't find this a very compelling argument.

~~~
grossvogel
I think the post describes a way in which this particular abstraction is
"leaky." We have to hope that the abstractions we rely on every day are less
leaky and thus allow us to get by without intimate knowledge of the underlying
complexity.

[http://www.joelonsoftware.com/articles/LeakyAbstractions.htm...](http://www.joelonsoftware.com/articles/LeakyAbstractions.html)

