im 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -31
  3. data/lib/im/loader.rb +1 -1
  4. data/lib/im/version.rb +1 -1
  5. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a146ab43403d85ad1ba24849e235c4c3f9c6f1f344c350f93f7815163ad0ec17
4
- data.tar.gz: 88f76dc7b193e2566b6603f4828ba07cade314dc08853b4941bce01df442954f
3
+ metadata.gz: e1708fffea9fb79c809dbfa34669e5471556e4d969ae8d95e689cfccc5c6f3e4
4
+ data.tar.gz: bce10f72bc879a53bda624ced7534bd0c74fc5666c6ff8545ea9371521edc8b0
5
5
  SHA512:
6
- metadata.gz: 53b9300337db2c3c716b9527f16ad78b29e65629da09306e22f48312907ef18d9e66f34e5b7a627dd7cf5daee00fd79953b222984937e43c49dd9f20934d6af2
7
- data.tar.gz: 706be184a19a39e665c8324c69b98bcd847f908c206382338b933470e803a7503c3b376227c6be6913ebe8630c83f4c865d9f943a76bcaaa224931139b8e09f9
6
+ metadata.gz: a112f1ee72916d690c0227a94a16f87d283b93a059f1e01d8681649ac9405ce46add46650234b2e337ace8b8571c64ba4f722f256099263eea04cfaafb3f02e1
7
+ data.tar.gz: b7a03df97bcbac97f09c8637f9c8b82fbaaddcd58640aecc2406e821910fe5cb2ed4200ddc2d6490bc0d0d2d42e6a65173bb7a52ba78c7ed2c05126a0edc669b
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # Im
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/im.svg)][gem]
3
4
  [![Build Status](https://github.com/shioyama/im/actions/workflows/ci.yml/badge.svg)][actions]
4
5
 
6
+ [gem]: https://rubygems.org/gems/im
5
7
  [actions]: https://github.com/shioyama/im/actions
6
8
 
7
9
  <!-- TOC -->
@@ -28,13 +30,12 @@ any way touching the global namespace.
28
30
  To do this, Im leverages code autoloading, Zeitwerk conventions around file
29
31
  structure and naming, and two features added in Ruby 3.2: `Kernel#load`
30
32
  with a module argument[^1] and `Module#const_added`[^2]. Since these Ruby
31
- features are essential to its design, it cannot be used with earlier versions
33
+ features are essential to its design, Im is not usable with earlier versions
32
34
  of Ruby.
33
35
 
34
- Im started its life as a fork of Zeitwerk and has a very similar interface. The
35
- gem strives to follow the Zeitwerk pattern as much as possible. Im and Zeitwerk
36
- can be used alongside each other provided there is no overlap between file
37
- paths managed by each gem.
36
+ Im started its life as a fork of Zeitwerk and has a very similar interface. Im
37
+ and Zeitwerk can be used alongside each other provided there is no overlap
38
+ between file paths managed by each gem.
38
39
 
39
40
  Im is in active development and should be considered experimental until the
40
41
  eventual release of version 1.0. Versions 0.1.6 and earlier of the gem were
@@ -43,12 +44,12 @@ part of a different experiment and are unrelated to the current gem.
43
44
  <a id="markdown-synopsis" name="synopsis"></a>
44
45
  ## Synopsis
45
46
 
46
- Im follows an interface that is in most respects identical to Zeitwerk.
47
- The central difference is that whereas Zeitwerk loads constants into the global
47
+ Im's public interface is in most respects identical to that of Zeitwerk. The
48
+ central difference is that whereas Zeitwerk loads constants into the global
48
49
  namespace (rooted in `Object`), Im loads them into anonymous namespaces rooted
49
- on the loader itself. Loaders in Im are a subclass of the `Module` class, and
50
- thus each one can define its own namespace. Since there can be arbitrarily many
51
- loaders, there can also be arbitrarily many autoloaded namespaces.
50
+ on the loader itself. `Im::Loader` is a subclass of `Module`, and thus each
51
+ loader instance can define its own namespace. Since there can be arbitrarily
52
+ many loaders, there can also be arbitrarily many autoloaded namespaces.
52
53
 
53
54
  Im's gem interface looks like this:
54
55
 
@@ -66,7 +67,7 @@ end
66
67
  loader.eager_load # optionally
67
68
  ```
68
69
 
69
- The generic interface is likewise identical to Zeitwerk's:
70
+ The generic interface is identical to Zeitwerk's:
70
71
 
71
72
  ```ruby
72
73
  loader = Zeitwerk::Loader.new
@@ -84,7 +85,7 @@ Object.const_defined?(:MyGem)
84
85
  ```
85
86
 
86
87
  In order to prevent leakage, the gem's entrypoint, in this case
87
- `lib/my_gem.rb`), must not define anything at toplevel, hence the use of
88
+ `lib/my_gem.rb`, must not define anything at toplevel, hence the use of
88
89
  `module loader::MyGem`.
89
90
 
90
91
  Once the entrypoint has been required, all constants defined within the gem's
@@ -107,7 +108,7 @@ foo = loader::MyGem::Foo
107
108
  # loads `Foo` from lib/my_gem/foo.rb
108
109
 
109
110
  foo.new.hello_world
110
- # "Hello World!"
111
+ #=> "Hello World!"
111
112
  ```
112
113
 
113
114
  Constants under the loader can be given permanent names that are different from
@@ -116,16 +117,12 @@ the one defined in the gem itself:
116
117
  ```ruby
117
118
  Bar = loader::MyGem::Foo
118
119
  Bar.new.hello_world
119
- # "Hello World!"
120
+ #=> "Hello World!"
120
121
  ```
121
122
 
122
- Since Im uses loaders as its namespace roots, it is important that consumers of
123
- gems have a way to fetch the loader for a given file path.
124
-
125
- The loader variable can go out of scope. Like Zeitwerk, Im keeps a registry
126
- with all of them, and so the object won't be garbage collected. For
127
- convenience, Im also provides a method, `Im#import`, to fetch a loader for
128
- a given file path:
123
+ Like Zeitwerk, Im keeps a registry of all loaders, so the loader objects won't
124
+ be garbage collected. For convenience, Im also provides a method, `Im#import`,
125
+ to fetch a loader for a given file path:
129
126
 
130
127
  ```ruby
131
128
  require "im"
@@ -133,7 +130,7 @@ require "my_gem"
133
130
 
134
131
  extend Im
135
132
  my_gem = import "my_gem"
136
- #=> loader::MyGem is autoloadable
133
+ #=> my_gem::MyGem is autoloadable
137
134
  ```
138
135
 
139
136
  Reloading works like Zeitwerk:
@@ -209,15 +206,15 @@ anywhere in the global namespace.
209
206
  ### Relative and absolute cpaths
210
207
 
211
208
  Im uses two types of constant paths: relative and absolute, wherever possible
212
- defaulting to relative ones. A relative cpath is a constant name relative to
209
+ defaulting to relative ones. A _relative cpath_ is a constant name relative to
213
210
  the loader in which it was originally defined, regardless of any other names it
214
- was assigned. Whereas Zeitwerk uses absolute cpaths, Im uses relative cpaths for
215
- all external loader APIs (see usage for examples).
211
+ was later assigned. Whereas Zeitwerk uses absolute cpaths, Im uses relative
212
+ cpaths for all external loader APIs (see usage for examples).
216
213
 
217
214
  To understand these concepts, it is important first to distinguish between two
218
215
  types of names in Ruby: _temporary names_ and _permanent names_.
219
216
 
220
- A temporary name is a constant name on an anonymous-rooted namespace, for
217
+ A _temporary name_ is a constant name on an anonymous-rooted namespace, for
221
218
  example a loader:
222
219
 
223
220
  ```ruby
@@ -228,7 +225,7 @@ my_gem::Foo.name
228
225
  ```
229
226
 
230
227
  Here, the string `"#<Im::Loader ...>::Foo"` is called a temporary name. We can
231
- give this module a permanent name by assigning it to a toplevel constant:
228
+ give this module a _permanent name_ by assigning it to a toplevel constant:
232
229
 
233
230
  ```ruby
234
231
  Bar = my_gem::Foo
@@ -244,12 +241,12 @@ keys in Im's internal registries to index constants and their autoloads, which
244
241
  is critical for successful autoloading.
245
242
 
246
243
  To get around this issue, Im tracks all module names and uses relative naming
247
- inside loader code. You can get the name of a module relative to the loader
248
- that loaded it with `Im::Loader#relative_cpath`:
244
+ inside loader code. Internally, Im has a method, `relative_cpath`, which can
245
+ generate any module name under a module in the loader namespace:
249
246
 
250
247
  ```ruby
251
- my_gem.relative_cpath(my_gem::Foo)
252
- #=> "Foo"
248
+ my_gem.send(:relative_cpath, loader::Foo, :Baz)
249
+ #=> "Foo::Baz"
253
250
  ```
254
251
 
255
252
  Using relative cpaths frees Im from depending on `Module#name` for
data/lib/im/loader.rb CHANGED
@@ -390,7 +390,7 @@ module Im
390
390
  def autoload_subdir(parent, cname, subdir)
391
391
  if autoload_path = autoload_path_set_by_me_for?(parent, cname)
392
392
  absolute_cpath = cpath(parent, cname)
393
- relative_cpath = relative_cpath(parent, cname)
393
+ relative_cpath = relative_cpath(absolute_cpath, cname)
394
394
  register_explicit_namespace(cpath, relative_cpath) if ruby?(autoload_path)
395
395
 
396
396
  # We do not need to issue another autoload, the existing one is enough
data/lib/im/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Im
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: im
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Salzberg