aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source/constant_autoloading_and_reloading.md
diff options
context:
space:
mode:
authorXavier Noria <fxn@hashref.com>2014-12-17 19:30:12 +0100
committerXavier Noria <fxn@hashref.com>2014-12-17 19:30:15 +0100
commit2e0429a511c670e0b3f55a9718144a3fc36d677d (patch)
treeedd09871358ea3dfeaaa464031fbcdd81e6e8436 /guides/source/constant_autoloading_and_reloading.md
parentfe46f009be1ece58e45abc51195e2381a71bd023 (diff)
downloadrails-2e0429a511c670e0b3f55a9718144a3fc36d677d.tar.gz
rails-2e0429a511c670e0b3f55a9718144a3fc36d677d.tar.bz2
rails-2e0429a511c670e0b3f55a9718144a3fc36d677d.zip
simpler example for the non-missing constants gotcha [ci skip]
The previous example was a little convoluted and the exposition claifying the parts that were correct albeit not totally obvious were interferring in my view. This example has less things going on and gets to the key problem with less balls in the air.
Diffstat (limited to 'guides/source/constant_autoloading_and_reloading.md')
-rw-r--r--guides/source/constant_autoloading_and_reloading.md81
1 files changed, 39 insertions, 42 deletions
diff --git a/guides/source/constant_autoloading_and_reloading.md b/guides/source/constant_autoloading_and_reloading.md
index 4eb9cc16ad..c552f2bfa3 100644
--- a/guides/source/constant_autoloading_and_reloading.md
+++ b/guides/source/constant_autoloading_and_reloading.md
@@ -1062,68 +1062,65 @@ spots.
### When Constants aren't Missed
-Let's consider an `Image` model, superclass of `Hotel::Image`:
+Let's consider a flight simulator. The application has a default flight model
```ruby
-# app/models/image.rb
-class Image
-end
-
-# app/models/hotel/image.rb
-module Hotel
- class Image < Image
- end
+# app/models/flight_model.rb
+class FlightModel
end
```
-No matter which file is interpreted first, `app/models/hotel/image.rb` is
-well-defined.
-
-Now consider a third file with this apparently harmless code:
+that can be overriden by each airplane, for instance
```ruby
-# app/models/hotel/poster.rb
-module Hotel
- class Poster < Image
+# app/models/bell_x1/flight_model.rb
+module BellX1
+ class FlightModel < FlightModel
end
end
-```
-
-The intention is to subclass `Hotel::Image`, but which is actually the
-superclass of `Hotel::Poster`? Well, it depends on the order of execution:
-
-1. If neither `app/models/image.rb` nor `app/models/hotel/image.rb` have been
-loaded at that point, the superclass is `Hotel::Image` because Rails is told
-`Hotel` is missing a constant called "Image" and loads
-`app/models/hotel/image.rb`. Good.
-2. If `app/models/hotel/image.rb` has been loaded at that point, the superclass
-is `Hotel::Image` because Ruby is able to resolve the constant. Good.
+# app/models/bell_x1/aircraft.rb
+module BellX1
+ class Aircraft
+ def initialize
+ @flight_model = FlightModel.new
+ end
+ end
+end
+```
-3. Lastly, if only `app/models/image.rb` has been loaded so far, the superclass
-is `Image`. Gotcha!
+The initializer wants to create a `BellX1::FlightModel` and nesting has
+`BellX1`, that looks good. But if the default flight model is loaded and the
+one for the Bell-X1 is not, the interpreter is able to resolve the top-level
+`FlightModel` and autoloading is thus not triggered for `BellX1::FlightModel`.
-The last scenario (3) may be surprising. Why isn't `Hotel::Image` autoloaded?
-Because Ruby is able to resolve `Image` as a top-level constant, so
-autoloading does not even get a chance.
+That code depends on the execution path.
-Most of the time, these kind of ambiguities can be resolved using qualified
-constants. In this case we would write
+These kind of ambiguities can often be resolved using qualified constants:
```ruby
-module Hotel
- class Poster < Hotel::Image
+module BellX1
+ class Plane
+ def flight_model
+ @flight_model ||= BellX1::FlightModel.new
+ end
end
end
```
-That class definition now is robust.
+Also, `require_dependency` is a solution:
+
+```ruby
+require_dependency 'bell_x1/flight_model'
-It is interesting to note here that the fix works because `Hotel` is a module, and
-`Hotel::Image` won’t look for `Image` in `Object` as it would if `Hotel` was a
-class with `Object` in its ancestors. If `Hotel` was a class we would resort to
-loading `Hotel::Image` with `require_dependency`. Furthermore, with that
-solution the qualified name would no longer be necessary.
+module BellX1
+ class Plane
+ def flight_model
+ @flight_model ||= FlightModel.new
+ end
+ end
+end
+```
### Autoloading within Singleton Classes