autoloaded 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/History.md +4 -0
  4. data/README.md +411 -60
  5. data/autoloaded.gemspec +19 -14
  6. data/lib/autoloaded.rb +104 -91
  7. data/lib/autoloaded/autoloader.rb +260 -0
  8. data/lib/autoloaded/compatibility/refine_and_using.rb +2 -0
  9. data/lib/autoloaded/constant.rb +5 -2
  10. data/lib/autoloaded/deprecation.rb +50 -0
  11. data/lib/autoloaded/inflection.rb +71 -0
  12. data/lib/autoloaded/load_pathed_directory.rb +112 -0
  13. data/lib/autoloaded/refine.rb +7 -1
  14. data/lib/autoloaded/refine/string.rb +7 -0
  15. data/lib/autoloaded/refine/string/to_source_filename.rb +12 -0
  16. data/lib/autoloaded/specification.rb +97 -0
  17. data/lib/autoloaded/specifications.rb +66 -0
  18. data/lib/autoloaded/version.rb +3 -1
  19. data/lib/autoloaded/warning.rb +125 -0
  20. data/spec/autoloaded/autoloader_spec.rb +469 -0
  21. data/spec/autoloaded/constant_spec.rb +0 -2
  22. data/spec/autoloaded/deprecation_spec.rb +23 -0
  23. data/spec/autoloaded/inflection_spec.rb +30 -0
  24. data/spec/autoloaded/load_pathed_directory_spec.rb +120 -0
  25. data/spec/autoloaded/refine/string/to_source_filename_spec.rb +0 -2
  26. data/spec/autoloaded/specification_spec.rb +98 -0
  27. data/spec/autoloaded/specifications_spec.rb +191 -0
  28. data/spec/autoloaded/version_spec.rb +0 -2
  29. data/spec/autoloaded/warning_spec.rb +115 -0
  30. data/spec/autoloaded_macro_sharedspec.rb +24 -0
  31. data/spec/autoloaded_spec.rb +277 -95
  32. data/spec/fixtures/autoloaded_with_conventional_filename.rb +3 -1
  33. data/spec/fixtures/autoloaded_with_conventional_filename/nested.rb +12 -1
  34. data/spec/fixtures/autoloaded_with_conventional_filename/nested/doubly_nested.rb +9 -0
  35. data/spec/fixtures/autoloaded_with_unconventional_filename.rb +12 -0
  36. data/spec/fixtures/autoloaded_with_unconventional_filename/N-est-ed.rb +7 -0
  37. data/spec/fixtures/autoloaded_with_unconventional_filename/nest_ed.rb +1 -0
  38. data/spec/fixtures/autoloaded_with_unconventional_filename/old_school_autoload.rb +5 -0
  39. data/spec/fixtures/not_autoloaded/nested.rb +1 -0
  40. data/spec/fixtures/old_api/autoloaded_with_conventional_filename.rb +10 -0
  41. data/spec/fixtures/old_api/autoloaded_with_conventional_filename/N-est-ed.rb +1 -0
  42. data/spec/fixtures/old_api/autoloaded_with_conventional_filename/nest_ed.rb +1 -0
  43. data/spec/fixtures/old_api/autoloaded_with_conventional_filename/nested.rb +5 -0
  44. data/spec/fixtures/old_api/autoloaded_with_conventional_filename/old_school_autoload.rb +5 -0
  45. data/spec/fixtures/{autoloaded_with_conventional_filename_only.rb → old_api/autoloaded_with_conventional_filename_only.rb} +1 -1
  46. data/spec/fixtures/{autoloaded_with_conventional_filename_only → old_api/autoloaded_with_conventional_filename_only}/nested.rb +0 -0
  47. data/spec/fixtures/{autoloaded_with_conventional_filename_only → old_api/autoloaded_with_conventional_filename_only}/old_school_autoload.rb +0 -0
  48. data/spec/fixtures/{autoloaded_with_unconventional_filenames.rb → old_api/autoloaded_with_unconventional_filenames.rb} +1 -1
  49. data/spec/fixtures/{autoloaded_with_unconventional_filenames → old_api/autoloaded_with_unconventional_filenames}/N-est-ed.rb +0 -0
  50. data/spec/fixtures/{autoloaded_with_unconventional_filenames → old_api/autoloaded_with_unconventional_filenames}/nest_ed.rb +0 -0
  51. data/spec/fixtures/{autoloaded_with_unconventional_filenames → old_api/autoloaded_with_unconventional_filenames}/old_school_autoload.rb +0 -0
  52. data/spec/fixtures/old_api/not_autoloaded.rb +6 -0
  53. data/spec/fixtures/old_api/not_autoloaded/nested.rb +1 -0
  54. data/spec/fixtures/old_api/not_autoloaded/old_school_autoload.rb +5 -0
  55. data/spec/matchers.rb +4 -33
  56. data/spec/spec_helper.rb +2 -0
  57. metadata +95 -41
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c8931d8ff044c161e9a4ac8a2b5ff68dcb567f4b
4
- data.tar.gz: 85a1ad725f3204618a2e08937819a1249cc88b8c
3
+ metadata.gz: d675263480f333ea77af9172b0350774ce55a4e3
4
+ data.tar.gz: 167f64690ba5c4d7c1620859c363dad0b561cd38
5
5
  SHA512:
6
- metadata.gz: 648c600b35a0068b001ba3ada55454c98a29bc55bec37c458d024d05137fc6a08b2625c320b09508b63e598d47b29d682d466ec875f6a56153f3f522f6fd60b1
7
- data.tar.gz: d927ce04c49c708d784763b7d563e2189e6f9b195c2261ca3ba6bdcd01d0f295bd0599bd71652eaff5671be51c8c46cd089a2c2f62e5635d664213b7b103f07f
6
+ metadata.gz: adade785b5342753a9561d3c0a6e1efcda22cf9ce8ef20ab13313b98532cf9db8ff9bb7ac43dd776cbbb0b29813c4b69cd711eae5278e93b14a0ac38567f71b6
7
+ data.tar.gz: aff0f5212fd8a289acaddc73e69275e7c1da5225be45f956f0094d3ac37e3e9393533a9802c08e2ab0eeec110e5c79e2fe599521e09c5b0782e430ec73190f7b
data/.travis.yml CHANGED
@@ -2,7 +2,7 @@ language: ruby
2
2
  bundler_args: --without debug doc tooling
3
3
  rvm:
4
4
  - 2.0
5
- - 2.1.0
5
+ - 2.1
6
6
  - ruby-head
7
7
  - jruby-head
8
8
  script: "bundle exec rake test"
data/History.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Version history for the _Autoloaded_ project
2
2
 
3
+ ## <a name="v1.3.0"></a>v1.3.0, Fri 12/26/2013
4
+
5
+ * Add support for relative class references with a new API
6
+
3
7
  ## <a name="v1.2.0"></a>v1.2.0, Fri 11/28/2013
4
8
 
5
9
  * Add support for [JRuby][JRuby] (Ruby v2.x-compatible versions)
data/README.md CHANGED
@@ -5,19 +5,21 @@
5
5
  [![Travis CI build status] ][Travis-CI-build-status]
6
6
  [![Code Climate quality report] ][Code-Climate-report]
7
7
  [![Code Climate coverage report]][Code-Climate-report]
8
+
8
9
  [![Gemnasium build status] ][Gemnasium-build-status]
9
10
  [![Inch CI build status] ][Inch-CI-build-status]
10
11
  [![RubyGems release] ][RubyGems-release]
11
12
 
12
- _Autoloaded_ dynamically and flexibly loads source files in a directory when a
13
- corresponding constant is dereferenced. It offers several advantages over other
14
- autoloading facilities such as those provided by the
15
- [Ruby Core library][Ruby-Core-Module-autoload] and the
16
- [ActiveSupport][ActiveSupport-Autoload] gem:
13
+ If you like the [_Module#autoload_][Ruby-Core-Module-autoload] feature of the
14
+ Ruby Core library, you may have wished for _Autoloaded_. It eliminates the
15
+ drudgery of handcrafting an `autoload` statement for each Ruby source code file
16
+ in your project. It also avoids the limitations of rigid convention-driven
17
+ facilities such as those provided by the [ActiveSupport][ActiveSupport-Autoload]
18
+ RubyGem.
17
19
 
18
- * It does not require a separate `autoload` statement for each constant
19
- * It does not enforce `CamelCase` to `snake_case` correspondence between the
20
- names of constants and source files
20
+ _Autoloaded_ assumes, but does not enforce, `CamelCase`-to-`snake_case`
21
+ correspondence between the names of constants and source files. You can combine
22
+ conventions, even putting multiple autoloaded constants in a single source file.
21
23
 
22
24
  ## Installation
23
25
 
@@ -25,8 +27,20 @@ Install [the RubyGem][RubyGems-release].
25
27
 
26
28
  $ gem install autoloaded
27
29
 
28
- Or you may want to make Autoloaded a dependency of your project by using
29
- [Bundler][Bundler]
30
+ Use _Autoloaded_ in your RubyGem project by making it a runtime dependency.
31
+
32
+ ```ruby
33
+ # my_awesome_gem.gemspec
34
+
35
+ Gem::Specification.new do |spec|
36
+ # ...
37
+ spec.add_dependency 'autoloaded', '~> 1'
38
+ # ...
39
+ end
40
+ ```
41
+
42
+ Or you may want to make _Autoloaded_ a dependency of your project by using
43
+ [Bundler][Bundler].
30
44
 
31
45
  ```ruby
32
46
  # Gemfile
@@ -38,99 +52,435 @@ gem 'autoloaded', '~> 1'
38
52
 
39
53
  ## Usage
40
54
 
41
- Suppose you have the following source files:
55
+ Suppose you have the following source files.
56
+
57
+ lib/
58
+ ├─ my_awesome_gem/
59
+ │  ├─ db/
60
+ │  │ ├─ MicroSoft.rb
61
+ │  │ ├─ SELF-DESTRUCT!.rb
62
+ │  │ ├─ mysql.rb
63
+ │  │ ├─ oracle.rb
64
+ │  │ └─ postgre_sql.rb
65
+ │  ├─ db.rb
66
+ │  └─ version.rb
67
+ └─ my_awesome_gem.rb
68
+
69
+ ### The _Autoloaded.module_ or _Autoloaded.class_ method
42
70
 
43
- * lib/
44
- * my_awesome_gem/
45
- * db/
46
- * mysql.rb
47
- * postgresql.rb
48
- * sql_server.rb
49
- * db.rb
50
- * my_awesome_gem.rb
71
+ The _Autoloaded.module_ and _Autoloaded.class_ method calls below invoke
72
+ [_Module#autoload_][Ruby-Core-Module-autoload] for each source file in the
73
+ calling module’s corresponding directory. Note that these methods must receive a
74
+ block, even if it’s an empty block.
51
75
 
52
- The following statements establish autoloading one statement per namespace:
76
+ The file paths used are abbreviated, if possible, using a directory of the Ruby
77
+ load path (`$:`). They are also rendered without their _.rb_ extension.
53
78
 
54
79
  ```ruby
55
80
  # lib/my_awesome_gem.rb
56
81
  module MyAwesomeGem
57
82
 
58
- extend Autoloaded
83
+ Autoloaded.module { }
84
+
85
+ # The above is the equivalent of:
86
+ #
87
+ # autoload :Db, 'my_awesome_gem/db'
88
+ # autoload :Version, 'my_awesome_gem/version'
59
89
 
60
90
  end
61
91
 
62
92
  # lib/my_awesome_gem/db.rb
63
93
  module MyAwesomeGem
64
94
 
65
- module DB
95
+ class DB
96
+
97
+ # The 'class' and 'module' methods are aliases -- use either one.
98
+ Autoloaded.class { }
66
99
 
67
- extend Autoloaded
100
+ # The above is the equivalent of:
101
+ #
102
+ # autoload :MicroSoft, 'my_awesome_gem/db/MicroSoft'
103
+ # autoload :SELF_DESTRUCT_, 'my_awesome_gem/db/SELF-DESTRUCT!'
104
+ # autoload :Mysql, 'my_awesome_gem/db/mysql'
105
+ # autoload :Oracle, 'my_awesome_gem/db/oracle'
106
+ # autoload :PostgreSql, 'my_awesome_gem/db/postgre_sql'
68
107
 
69
108
  end
70
109
 
71
110
  end
72
111
  ```
73
112
 
74
- Note that your preferred casing of constants is accommodated automatically.
113
+ The code above is succinct, but it’s not exactly correct. The constants
114
+ `MyAwesomeGem::DB`, `MyAwesomeGem::DB::MySQL`, and others are not set up to
115
+ autoload properly because they are misspelled (case-sensitively speaking).
75
116
 
76
117
  ```ruby
77
- # Unlike Kernel#autoload and Module#autoload, Autoloaded is not clairvoyant about
78
- # what constants will be autoloaded.
79
- MyAwesomeGem::DB.constants # => []
80
-
81
- # But like Kernel#autoload and Module#autoload, Autoloaded does tell you which
82
- # source files will be autoloaded. (The difference is that it may return an array
83
- # of potential matches instead of just one filename.)
84
- MyAwesomeGem::DB.autoload? :MySQL # => 'db/mysql'
85
- MyAwesomeGem::DB.autoload? :PostgreSQL # => 'db/postgresql'
86
- MyAwesomeGem::DB.autoload? :SQLServer # => 'db/sql_server'
87
- MyAwesomeGem::DB.autoload? :Nonexistent # => nil
88
-
89
- MyAwesomeGem::DB::MySQL
90
- MyAwesomeGem::DB.constants # => [:MySQL]
91
- MyAwesomeGem::DB::PostgreSQL
92
- MyAwesomeGem::DB.constants # => [:MySQL, :PostgreSQL]
93
- MyAwesomeGem::DB::SQLServer
94
- MyAwesomeGem::DB.constants # => [:MySQL, :PostgreSQL, :SQLServer]
118
+ MyAwesomeGem.autoload? :DB # => nil
119
+ MyAwesomeGem.const_defined? :DB # => false
120
+ MyAwesomeGem.constants.include? :DB # => false
121
+
122
+ MyAwesomeGem::DB # Raises NameError because lib/my_awesome_gem/db.rb does not
123
+ # get autoloaded!
124
+
125
+ MyAwesomeGem.autoload? :Db # => 'my_awesome_gem/db' (a lie!)
126
+ MyAwesomeGem.const_defined? :Db # => true (a lie!)
127
+ MyAwesomeGem.constants.include? :Db # => true (a lie!)
128
+
129
+ MyAwesomeGem::Db # Raises NameError because lib/my_awesome_gem/db.rb defines
130
+ # MyAwesomeGem::DB, not MyAwesomeGem::Db!
131
+
132
+ #################################################################################
133
+
134
+ require 'my_awesome_gem/db'
135
+
136
+ MyAwesomeGem::DB.autoload? :MySQL # => nil
137
+ MyAwesomeGem::DB.const_defined? :MySQL # => false
138
+ MyAwesomeGem::DB.constants.include? :MySQL # => false
139
+
140
+ MyAwesomeGem::DB::MySQL # Raises NameError because
141
+ # lib/my_awesome_gem/db/mysql.rb does not get
142
+ # autoloaded!
143
+
144
+ MyAwesomeGem::DB.autoload? :Mysql # => 'my_awesome_gem/db/mysql' (a lie!)
145
+ MyAwesomeGem::DB.const_defined? :Mysql # => true (a lie!)
146
+ MyAwesomeGem::DB.constants.include? :Mysql # => true (a lie!)
147
+
148
+ MyAwesomeGem::DB::Mysql # Raises NameError because
149
+ # lib/my_awesome_gem/db/mysql.rb defines
150
+ # MyAwesomeGem::DB::MySQL, not MyAwesomeGem::DB::Mysql!
95
151
  ```
96
152
 
97
- _Autoloaded_ does not perform deep autoloading of nested namespaces and
98
- directories. This is by design.
153
+ ### The `with` specification
154
+
155
+ _Autoloaded_ needs hints from you concerning unpredictable spellings,
156
+ stylization, and organization of constant names and/or source file names. You can
157
+ specify `with` as:
99
158
 
100
- ### Important note
159
+ * A symbol or array of symbols representing constants to autoload
160
+ * A hash of symbols and strings representing constants and the source filename(s)
161
+ from which to autoload them
162
+ * A combination of the above
101
163
 
102
- You must extend a namespace with _Autoloaded_ **from within the file in which the
103
- namespace is defined**. This is because _Autoloaded_ utilizes the source file
104
- path of the namespace to establish which directory will be autoloaded. That path
105
- is discoverable only via the stack trace of `extend Autoloaded`.
164
+ A symbol provided to `with` signifies the name of a constant, and a string
165
+ signifies the name of a source file.
106
166
 
107
- In the following example, autoloading of the _MyAwesomeGem_ namespace will not
108
- occur because the name of the source file in which the `extend` statement is
109
- invoked does not match the name of the namespace.
167
+ Specifying `with` does not filter the source files; it maps the source files to
168
+ different constants, or tweaks the names of constants.
169
+
170
+ You can specify `with` multiple times, and its effects are cumulative.
110
171
 
111
172
  ```ruby
112
173
  # lib/my_awesome_gem.rb
113
- module MyAwesomeGem; end
174
+ module MyAwesomeGem
175
+
176
+ Autoloaded.module do |autoloaded|
177
+ autoloaded.with :DB, :VERSION
178
+ # Or:
179
+ # autoloaded.with :DB
180
+ # autoloaded.with :VERSION
181
+ # Or:
182
+ # autoloaded.with DB: 'db', VERSION: 'version'
183
+ # Or:
184
+ # autoloaded.with DB: 'db'
185
+ # autoloaded.with VERSION: 'version'
186
+ # Or:
187
+ # autoloaded.with 'db' => :DB, 'version' => :VERSION
188
+ # Or:
189
+ # autoloaded.with 'db' => :DB
190
+ # autoloaded.with 'version' => :VERSION
191
+ end
192
+
193
+ # The above is the equivalent of:
194
+ #
195
+ # autoload :DB, 'my_awesome_gem/db'
196
+ # autoload :VERSION, 'my_awesome_gem/version'
197
+
198
+ end
199
+
200
+ # lib/my_awesome_gem/db.rb
201
+ module MyAwesomeGem
202
+
203
+ class DB
204
+
205
+ Autoloaded.class do |autoloaded|
206
+ autoloaded.with :MySQL, :PostgreSQL, [:Access, :SQLServer] => 'MicroSoft'
207
+ # Or:
208
+ # autoloaded.with :MySQL,
209
+ # :PostgreSQL,
210
+ # Access: 'MicroSoft',
211
+ # SQLServer: 'MicroSoft'
212
+ # Or:
213
+ # autoloaded.with :MySQL, :PostgreSQL, 'MicroSoft' => [:Access, :SQLServer]
214
+ # Or:
215
+ # autoloaded.with :MySQL,
216
+ # :PostgreSQL,
217
+ # 'MicroSoft' => :Access,
218
+ # 'MicroSoft' => :SQLServer
219
+ # Or ...
220
+ end
221
+
222
+ # The above is the equivalent of:
223
+ #
224
+ # autoload :Access, 'my_awesome_gem/db/MicroSoft'
225
+ # autoload :SQLServer, 'my_awesome_gem/db/MicroSoft'
226
+ # autoload :SELF_DESTRUCT_, 'my_awesome_gem/db/SELF-DESTRUCT!'
227
+ # autoload :MySQL, 'my_awesome_gem/db/mysql'
228
+ # autoload :Oracle, 'my_awesome_gem/db/oracle'
229
+ # autoload :PostgreSQL, 'my_awesome_gem/db/postgre_sql'
230
+
231
+ end
232
+
233
+ end
234
+ ```
235
+
236
+ Now you’re autoloading all the constants you want to be autoloading.
237
+
238
+ ```ruby
239
+ MyAwesomeGem.autoload? :DB # => 'my_awesome_gem/db'
240
+ MyAwesomeGem.const_defined? :DB # => true
241
+ MyAwesomeGem.constants.include? :DB # => true
242
+
243
+ MyAwesomeGem::DB # => MyAwesomeGem::DB
244
+
245
+ MyAwesomeGem.autoload? :Db # => nil
246
+ MyAwesomeGem.const_defined? :Db # => false
247
+ MyAwesomeGem.constants.include? :Db # => false
248
+
249
+ MyAwesomeGem::Db # Raises NameError as expected.
250
+
251
+ #################################################################################
252
+
253
+ MyAwesomeGem::DB.autoload? :MySQL # => 'my_awesome_gem/db/mysql'
254
+ MyAwesomeGem::DB.const_defined? :MySQL # => true
255
+ MyAwesomeGem::DB.constants.include? :MySQL # => true
256
+
257
+ MyAwesomeGem::DB::MySQL # => MyAwesomeGem::DB::MySQL
258
+
259
+ MyAwesomeGem::DB.autoload? :Mysql # => nil
260
+ MyAwesomeGem::DB.const_defined? :Mysql # => false
261
+ MyAwesomeGem::DB.constants.include? :Mysql # => false
262
+
263
+ MyAwesomeGem::DB::Mysql # Raises NameError as expected.
264
+ ```
265
+
266
+ ### The `except` and `only` specifications
267
+
268
+ What about source files you **don’t** want to be autoloaded?
269
+
270
+ ```ruby
271
+ MyAwesomeGem::DB::SELF_DESTRUCT_ # Loading this file does something bad, so
272
+ # let's not.
273
+ ```
274
+
275
+ If you really want to avoid loading *lib/my_awesome_gem/db/SELF-DESTRUCT!.rb*, so
276
+ much so that you don’t want an `autoload` statement made for it, specify
277
+ `except`.
278
+
279
+ ```ruby
280
+ # lib/my_awesome_gem/db.rb
281
+
282
+ module MyAwesomeGem
283
+
284
+ class DB
285
+
286
+ Autoloaded.class do |autoloaded|
287
+ autoloaded.with :MySQL, :PostgreSQL, [:Access, :SQLServer] => 'MicroSoft'
288
+
289
+ autoloaded.except 'SELF-DESTRUCT!'
290
+ # Or:
291
+ # autoloaded.except :SELF_DESTRUCT_
292
+ # Or ...
293
+ end
294
+
295
+ # The above is the equivalent of:
296
+ #
297
+ # autoload :Access, 'my_awesome_gem/db/MicroSoft'
298
+ # autoload :SQLServer, 'my_awesome_gem/db/MicroSoft'
299
+ # autoload :MySQL, 'my_awesome_gem/db/mysql'
300
+ # autoload :Oracle, 'my_awesome_gem/db/oracle'
301
+ # autoload :PostgreSQL, 'my_awesome_gem/db/postgre_sql'
302
+
303
+ end
304
+
305
+ end
306
+ ```
114
307
 
308
+ ```ruby
309
+ MyAwesomeGem::DB.autoload? :SELF_DESTRUCT_ # => nil
310
+ MyAwesomeGem::DB.const_defined? :SELF_DESTRUCT_ # => false
311
+ MyAwesomeGem::DB.constants.include? :SELF_DESTRUCT_ # => false
312
+
313
+ MyAwesomeGem::DB::SELF_DESTRUCT_ # Raises NameError as expected.
314
+ ```
315
+
316
+ You can specify `except` as:
317
+
318
+ * A symbol or array of symbols representing constants to avoid autoloading
319
+ * A string or array of strings representing source filenames to avoid autoloading
320
+ * A hash of symbols and/or strings representing constants and/or source filenames
321
+ to avoid autoloading
322
+ * A combination of the above
323
+
324
+ The `only` specification is like `except` but it has the opposite effect, namely,
325
+ that **only** specified constants and/or source files will be autoloaded.
326
+
327
+ You can specify `only` as:
328
+
329
+ * A symbol or array of symbols representing constants to autoload
330
+ * A string or array of strings representing source filenames to autoload
331
+ * A hash of symbols and/or strings representing constants and the source
332
+ filename(s) from which to autoload them
333
+ * A combination of the above
334
+
335
+ A symbol provided to `except` or `only` signifies the name of a constant, and a
336
+ string signifies the name of a source file.
337
+
338
+ You can specify `except` and `only` multiple times, and their effects are
339
+ cumulative.
340
+
341
+ ### The `from` specification
342
+
343
+ It’s recommended that you call _Autoloaded.module_ or _Autoloaded.class_ from
344
+ within the source file where your module or class is defined. This practice
345
+ allows _Autoloaded_ to assume that the source files to be autoloaded are in a
346
+ directory of the same name (and in the same location) as the module’s defining
347
+ source file.
348
+
349
+ There are circumstances, however, in which you cannot rely on the computed
350
+ directory for autoloading. Perhaps the directory has a different name from the
351
+ module’s defining source file. Or perhaps you are autoloading a library that you
352
+ didn’t author. In these situations you can specify `from` with the path from
353
+ which source files should be autoloaded.
354
+
355
+ ```ruby
356
+ # somewhere_else.rb
357
+
358
+ module MyAwesomeGem
359
+
360
+ Autoloaded.module do |autoloaded|
361
+ # The following code is not actually very useful since the installed location
362
+ # of a RubyGem varies with the operating system and user preferences. How to
363
+ # compute the path properly is outside the scope of this readme and is left
364
+ # as an exercise for the reader.
365
+ autoloaded.from '/absolute/path/to/my_awesome_gem'
366
+ end
367
+
368
+ end
369
+ ```
370
+
371
+ A path provided to `from` cannot be relative; it must start with the filesystem
372
+ root.
373
+
374
+ If you specify `from` multiple times in an _Autoloaded_ block, only the last one
375
+ takes effect.
376
+
377
+ ### The _Autoloaded.warn_ method
378
+
379
+ There are two circumstances under which _Autoloaded_ by default will write
380
+ warnings to stderr:
381
+
382
+ * Overriding an established autoload
383
+ * Establishing an autoload for a defined constant
384
+
385
+ You can silence these warnings by passing `false` to _Autoloaded.warn_. (Passing
386
+ `true` turns warnings on if they are off.)
387
+
388
+ ```ruby
115
389
  # lib/my_awesome_gem/db.rb
390
+
116
391
  module MyAwesomeGem
117
392
 
118
- # WRONG!
119
- extend Autoloaded
393
+ class DB
394
+
395
+ Autoloaded.warn false # Turn off Autoloaded warnings.
120
396
 
121
- module DB
397
+ autoload :SQLServer, 'my_awesome_gem/db/MicroSoft'
122
398
 
123
- extend Autoloaded
399
+ class Oracle; end
400
+
401
+ Autoloaded.class { } # This duplicates the 'autoload' statement and class
402
+ # definition above, but no Autoloaded warnings will be
403
+ # displayed.
404
+
405
+ Autoloaded.warn true # Turn on Autoloaded warnings again.
124
406
 
125
407
  end
126
408
 
127
409
  end
410
+ ```
411
+
412
+ Use the block form if you want to ensure warnings get toggled on or off for a
413
+ series of statements.
128
414
 
129
- # some_other_file.rb
130
- require 'my_awesome_gem'
131
- MyAwesomeGem::DB # NameError is raised!
415
+ ```ruby
416
+ # lib/my_awesome_gem/db.rb
417
+
418
+ module MyAwesomeGem
419
+
420
+ class DB
421
+
422
+ autoload :SQLServer, 'my_awesome_gem/db/MicroSoft'
423
+
424
+ class Oracle; end
425
+
426
+ Autoloaded.warn false do
427
+ Autoloaded.class { } # This duplicates the 'autoload' statement and class
428
+ # definition above, but no Autoloaded warnings will
429
+ # be displayed.
430
+ end
431
+
432
+ # Autoloaded warnings are turned on again automatically.
433
+
434
+ end
435
+
436
+ end
132
437
  ```
133
438
 
439
+ ### How to debug autoloading
440
+
441
+ The _Autoloaded.module_ or _Autoloaded.class_ method returns an ordered list of
442
+ arguments it has passed to `autoload`.
443
+
444
+ ```ruby
445
+ # lib/my_awesome_gem/db.rb
446
+
447
+ module MyAwesomeGem
448
+
449
+ class DB
450
+
451
+ results = Autoloaded.class do |autoloaded|
452
+ autoloaded.with :MySQL, :PostgreSQL, [:Access, :SQLServer] => 'MicroSoft'
453
+ autoloaded.except 'SELF-DESTRUCT!'
454
+ end
455
+ STDOUT.puts results.inspect # See output below.
456
+
457
+ end
458
+
459
+ end
460
+
461
+ # [[:Access, 'my_awesome_gem/db/MicroSoft' ],
462
+ # [:SQLServer, 'my_awesome_gem/db/MicroSoft' ],
463
+ # [:MySQL, 'my_awesome_gem/db/mysql' ],
464
+ # [:Oracle, 'my_awesome_gem/db/oracle' ],
465
+ # [:PostgreSQL, 'my_awesome_gem/db/postgre_sql']]
466
+ ```
467
+
468
+ You can also hook [_Module#autoload_][Ruby-Core-Module-autoload] and
469
+ [_Kernel#autoload_][Ruby-Core-Kernel-autoload] via monkeypatching or other means
470
+ in order to see what’s happening.
471
+
472
+ ### Source filenames are relative to the `from` specification
473
+
474
+ You may have noticed that source filenames in the above examples are not
475
+ absolute. They are relative to the _Autoloaded_ block’s `from` specification
476
+ (which I recommend that you allow to be computed for you —
477
+ [see above](#the-from-specification)).
478
+
479
+ ### Recursive autoloading not supported
480
+
481
+ _Autoloaded_ does not perform deep autoloading of nested namespaces and
482
+ directories. This is by design.
483
+
134
484
  ## Contributing
135
485
 
136
486
  1. [Fork][fork-Autoloaded] the official repository.
@@ -160,6 +510,7 @@ Released under the [MIT License][MIT-License].
160
510
  [Ruby-Core-Module-autoload]: http://ruby-doc.org/core/Module.html#method-i-autoload "‘Module#autoload’ method in the Ruby Core Library"
161
511
  [ActiveSupport-Autoload]: http://api.rubyonrails.org/classes/ActiveSupport/Autoload.html "‘ActiveSupport::Autoload’ module in the Rails API"
162
512
  [Bundler]: http://bundler.io
513
+ [Ruby-Core-Kernel-autoload]: http://ruby-doc.org/core/Kernel.html#method-i-autoload "‘Kernel#autoload’ method in the Ruby Core Library"
163
514
  [fork-Autoloaded]: https://github.com/njonsson/autoloaded/fork "Fork the official repository of Autoloaded"
164
515
  [compare-Autoloaded-branches]: https://github.com/njonsson/autoloaded/compare "Compare branches of Autoloaded repositories"
165
516
  [MIT-License]: http://github.com/njonsson/autoloaded/blob/master/License.md "MIT License claim for Autoloaded"