im 0.1.6 → 0.2.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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +21 -0
- data/README.md +245 -32
- data/lib/im/const_path.rb +48 -0
- data/lib/im/error.rb +24 -0
- data/lib/im/explicit_namespace.rb +96 -0
- data/lib/im/gem_inflector.rb +17 -0
- data/lib/im/gem_loader.rb +65 -0
- data/lib/im/inflector.rb +46 -0
- data/lib/im/internal.rb +12 -0
- data/lib/im/kernel.rb +34 -9
- data/lib/im/loader/callbacks.rb +93 -0
- data/lib/im/loader/config.rb +346 -0
- data/lib/im/loader/eager_load.rb +214 -0
- data/lib/im/loader/helpers.rb +123 -0
- data/lib/im/loader.rb +586 -0
- data/lib/im/module_const_added.rb +63 -0
- data/lib/im/registry.rb +166 -0
- data/lib/im/version.rb +1 -1
- data/lib/im.rb +18 -185
- metadata +25 -61
- data/CHANGELOG.md +0 -31
- data/Gemfile +0 -8
- data/Gemfile.lock +0 -37
- data/LICENSE.txt +0 -21
- data/Rakefile +0 -8
- data/lib/im/module.rb +0 -9
- data/lib/im/ruby_version_check.rb +0 -22
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Im::ModuleConstAdded
|
4
|
+
UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name)
|
5
|
+
private_constant :UNBOUND_METHOD_MODULE_NAME
|
6
|
+
|
7
|
+
# We patch Module#const_added to track every time a constant is added to a
|
8
|
+
# permanently-named module pointing to an Im-autoloaded constant. This is
|
9
|
+
# important because the moment that an Im-autoloaded constant is attached to
|
10
|
+
# a permanently named module, its name changes permanently. Although Im
|
11
|
+
# internally avoids the use of absolute cpaths, ExplicitNamespace must use
|
12
|
+
# them and thus we need to update its internal registry accordingly.
|
13
|
+
#
|
14
|
+
# @sig (Symbol) -> void
|
15
|
+
def const_added(const_name)
|
16
|
+
# If we are called from an autoload, no need to track.
|
17
|
+
return super if autoload?(const_name)
|
18
|
+
|
19
|
+
# Get the name of this module and only continue if it is a permanent name.
|
20
|
+
return unless cpath = Im.permanent_cpath(self)
|
21
|
+
|
22
|
+
# We know this is not an autoloaded constant, so it is safe to fetch the
|
23
|
+
# value. We fetch the value, get it's object_id, and check the registry to
|
24
|
+
# see if it is an Im-autoloaded module.
|
25
|
+
relative_cpath, loader, references = Im::Registry.autoloaded_modules[const_get(const_name).object_id]
|
26
|
+
return super unless loader
|
27
|
+
|
28
|
+
# Update the context for this const add. This is important for reloading so
|
29
|
+
# we can reset inbound references when the autoloaded module is unloaded.
|
30
|
+
references << [self, const_name]
|
31
|
+
|
32
|
+
# Update all absolute cpath references to this module by replacing all
|
33
|
+
# references to the original cpath with the new, permanently-named cpath.
|
34
|
+
#
|
35
|
+
# For example, if we had a module loader::Foo::Bar, and loader::Foo was
|
36
|
+
# assigned to Baz like this:
|
37
|
+
#
|
38
|
+
# Baz = loader::Foo
|
39
|
+
#
|
40
|
+
# then we must update cpaths from a string like
|
41
|
+
#
|
42
|
+
# "#<Im::Loader ...>::Foo::Bar"
|
43
|
+
#
|
44
|
+
# to
|
45
|
+
#
|
46
|
+
# "Baz::Bar"
|
47
|
+
#
|
48
|
+
# To do this, we take the loader's module_prefix ("#<Im::Loader ...>::"),
|
49
|
+
# append to it the relative cpath of the constant ("Foo") and replace that by the new
|
50
|
+
# name ("Baz"), roughly like this:
|
51
|
+
#
|
52
|
+
# "#<Im::Loader ...>::Foo::Bar".gsub(/^#{"#<Im::Loader ...>::Foo"}/, "Baz")
|
53
|
+
#
|
54
|
+
prefix = relative_cpath ? "#{loader.module_prefix}#{relative_cpath}" : loader.module_prefix.delete_suffix("::")
|
55
|
+
::Im::ExplicitNamespace.__update_cpaths(prefix, "#{cpath}::#{const_name}")
|
56
|
+
|
57
|
+
super
|
58
|
+
rescue NameError
|
59
|
+
super
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
::Module.prepend(Im::ModuleConstAdded)
|
data/lib/im/registry.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Im
|
4
|
+
module Registry # :nodoc: all
|
5
|
+
class << self
|
6
|
+
# Keeps track of all loaders. Useful to broadcast messages and to prevent
|
7
|
+
# them from being garbage collected.
|
8
|
+
#
|
9
|
+
# @private
|
10
|
+
# @sig Array[Im::Loader]
|
11
|
+
attr_reader :loaders
|
12
|
+
|
13
|
+
# Registers gem loaders to let `for_gem` be idempotent in case of reload.
|
14
|
+
#
|
15
|
+
# @private
|
16
|
+
# @sig Hash[String, Im::Loader]
|
17
|
+
attr_reader :gem_loaders_by_root_file
|
18
|
+
|
19
|
+
# Maps absolute paths to the loaders responsible for them.
|
20
|
+
#
|
21
|
+
# This information is used by our decorated `Kernel#require` to be able to
|
22
|
+
# invoke callbacks and autovivify modules.
|
23
|
+
#
|
24
|
+
# @private
|
25
|
+
# @sig Hash[String, Im::Loader]
|
26
|
+
attr_reader :autoloads
|
27
|
+
|
28
|
+
# @private
|
29
|
+
# @sig Hash[String, Im::Loader]
|
30
|
+
attr_reader :paths
|
31
|
+
|
32
|
+
# This hash table addresses an edge case in which an autoload is ignored.
|
33
|
+
#
|
34
|
+
# For example, let's suppose we want to autoload in a gem like this:
|
35
|
+
#
|
36
|
+
# # lib/my_gem.rb
|
37
|
+
# loader = Im::Loader.new
|
38
|
+
# loader.push_dir(__dir__)
|
39
|
+
# loader.setup
|
40
|
+
#
|
41
|
+
# module loader::MyGem
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# if you require "my_gem", as Bundler would do, this happens while setting
|
45
|
+
# up autoloads:
|
46
|
+
#
|
47
|
+
# 1. Object.autoload?(:MyGem) returns `nil` because the autoload for
|
48
|
+
# the constant is issued by Im while the same file is being
|
49
|
+
# required.
|
50
|
+
# 2. The constant `MyGem` is undefined while setup runs.
|
51
|
+
#
|
52
|
+
# Therefore, a directory `lib/my_gem` would autovivify a module according to
|
53
|
+
# the existing information. But that would be wrong.
|
54
|
+
#
|
55
|
+
# To overcome this fundamental limitation, we keep track of the constant
|
56
|
+
# paths that are in this situation ---in the example above, "MyGem"--- and
|
57
|
+
# take this collection into account for the autovivification logic.
|
58
|
+
#
|
59
|
+
# Note that you cannot generally address this by moving the setup code
|
60
|
+
# below the constant definition, because we want libraries to be able to
|
61
|
+
# use managed constants in the module body:
|
62
|
+
#
|
63
|
+
# module loader::MyGem
|
64
|
+
# include MyConcern
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# @private
|
68
|
+
# @sig Hash[String, [String, Im::Loader]]
|
69
|
+
attr_reader :inceptions
|
70
|
+
|
71
|
+
# @private
|
72
|
+
# @sig Hash[Integer, [Im::Loader, String, Array]]
|
73
|
+
attr_reader :autoloaded_modules
|
74
|
+
|
75
|
+
# Registers a loader.
|
76
|
+
#
|
77
|
+
# @private
|
78
|
+
# @sig (Im::Loader) -> void
|
79
|
+
def register_loader(loader)
|
80
|
+
loaders << loader
|
81
|
+
end
|
82
|
+
|
83
|
+
# @private
|
84
|
+
# @sig (Im::Loader) -> void
|
85
|
+
def unregister_loader(loader)
|
86
|
+
loaders.delete(loader)
|
87
|
+
gem_loaders_by_root_file.delete_if { |_, l| l == loader }
|
88
|
+
autoloads.delete_if { |_, l| l == loader }
|
89
|
+
paths.delete_if { |_, l| l == loader }
|
90
|
+
inceptions.delete_if { |_, (_, l)| l == loader }
|
91
|
+
autoloaded_modules.delete_if { |_, (_, l, _)| l == loader }
|
92
|
+
end
|
93
|
+
|
94
|
+
# This method returns always a loader, the same instance for the same root
|
95
|
+
# file. That is how Im::Loader.for_gem is idempotent.
|
96
|
+
#
|
97
|
+
# @private
|
98
|
+
# @sig (String) -> Im::Loader
|
99
|
+
def loader_for_gem(root_file, warn_on_extra_files:)
|
100
|
+
gem_loaders_by_root_file[root_file] ||= GemLoader._new(root_file, warn_on_extra_files: warn_on_extra_files)
|
101
|
+
end
|
102
|
+
|
103
|
+
# @private
|
104
|
+
# @sig (Im::Loader, String) -> String
|
105
|
+
def register_autoload(loader, abspath)
|
106
|
+
paths[abspath] = autoloads[abspath] = loader
|
107
|
+
end
|
108
|
+
|
109
|
+
# @private
|
110
|
+
# @sig (String) -> void
|
111
|
+
def unregister_autoload(abspath)
|
112
|
+
autoloads.delete(abspath)
|
113
|
+
end
|
114
|
+
|
115
|
+
# @private
|
116
|
+
# @sig (Im::Loader, String) -> String
|
117
|
+
def register_path(loader, abspath)
|
118
|
+
paths[abspath] = loader
|
119
|
+
end
|
120
|
+
|
121
|
+
# @private
|
122
|
+
# @sig (String) -> void
|
123
|
+
def unregister_path(abspath)
|
124
|
+
paths.delete(abspath)
|
125
|
+
end
|
126
|
+
|
127
|
+
# @private
|
128
|
+
# @sig (String, String, Im::Loader) -> void
|
129
|
+
def register_inception(cpath, abspath, loader)
|
130
|
+
inceptions[cpath] = [abspath, loader]
|
131
|
+
end
|
132
|
+
|
133
|
+
# @private
|
134
|
+
# @sig (String) -> String?
|
135
|
+
def inception?(cpath)
|
136
|
+
if pair = inceptions[cpath]
|
137
|
+
pair.first
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def register_autoloaded_module(mod, module_name, loader)
|
142
|
+
autoloaded_modules[mod.object_id] = [module_name, loader, []]
|
143
|
+
end
|
144
|
+
|
145
|
+
# @private
|
146
|
+
# @sig (String) -> Im::Loader?
|
147
|
+
def loader_for(path)
|
148
|
+
paths[path]
|
149
|
+
end
|
150
|
+
|
151
|
+
# @private
|
152
|
+
# @sig (Im::Loader) -> void
|
153
|
+
def on_unload(loader)
|
154
|
+
autoloads.delete_if { |_path, object| object == loader }
|
155
|
+
inceptions.delete_if { |_cpath, (_path, object)| object == loader }
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
@loaders = []
|
160
|
+
@gem_loaders_by_root_file = {}
|
161
|
+
@autoloads = {}
|
162
|
+
@paths = {}
|
163
|
+
@inceptions = {}
|
164
|
+
@autoloaded_modules = {}
|
165
|
+
end
|
166
|
+
end
|
data/lib/im/version.rb
CHANGED
data/lib/im.rb
CHANGED
@@ -1,193 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Im
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
unless tracer_originally_enabled = @tracer.enabled?
|
21
|
-
@tracer.enable
|
22
|
-
end
|
23
|
-
|
24
|
-
yield
|
25
|
-
ensure
|
26
|
-
@current_imports.pop
|
27
|
-
@tracer.disable unless tracer_originally_enabled
|
28
|
-
end
|
29
|
-
|
30
|
-
def current_import
|
31
|
-
current_imports.last
|
32
|
-
end
|
33
|
-
|
34
|
-
def importing?
|
35
|
-
!!current_import
|
36
|
-
end
|
37
|
-
|
38
|
-
def handle_require(path, caller_path)
|
39
|
-
resolved_path = resolve_path(path)
|
40
|
-
|
41
|
-
return yield unless resolved_path
|
42
|
-
|
43
|
-
if autoloaded = autoloads.delete(resolved_path)
|
44
|
-
return with_import(autoloaded) do
|
45
|
-
!!import(path)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
if importing?
|
50
|
-
registry[resolved_path] ||= Require.new(resolved_path, current_import)
|
51
|
-
elsif registry.key?(caller_path)
|
52
|
-
return with_import(registry[caller_path].import) do
|
53
|
-
!!import(resolved_path)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
loaded = yield # super
|
58
|
-
|
59
|
-
if required = registry[resolved_path]
|
60
|
-
if loaded && registry.key?(caller_path)
|
61
|
-
registry[caller_path].requires << required
|
62
|
-
end
|
63
|
-
|
64
|
-
imports = importing? ? current_imports : [Object]
|
65
|
-
import_constants(required, imports)
|
66
|
-
end
|
67
|
-
|
68
|
-
loaded
|
69
|
-
end
|
70
|
-
|
71
|
-
def handle_autoload(path)
|
72
|
-
if importing? && (resolved_path = resolve_path(path))
|
73
|
-
autoloads[resolved_path] = current_import
|
74
|
-
end
|
75
|
-
yield
|
76
|
-
end
|
77
|
-
|
78
|
-
def resolve_path(path)
|
79
|
-
(resolved = $:.resolve_feature_path(path)) && resolved[1]
|
80
|
-
end
|
81
|
-
|
82
|
-
def import_constants(required, imports)
|
83
|
-
return if imports.empty? || required.nil?
|
84
|
-
|
85
|
-
required.requires.each { |r| require r.path }
|
86
|
-
|
87
|
-
imports.each do |import|
|
88
|
-
required.defined_constants.each do |name, mod|
|
89
|
-
# Do not assign constants that are aliased to root namespace
|
90
|
-
root = name.to_s.split("::", 2)[0]
|
91
|
-
next if Object.const_defined?(root) &&
|
92
|
-
import.const_defined?(root, false) &&
|
93
|
-
Object.const_get(root) == import.const_get(root)
|
94
|
-
|
95
|
-
begin
|
96
|
-
import.const_set(name, mod) unless import.const_defined?(name, false)
|
97
|
-
rescue NameError
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
class Import < Module
|
105
|
-
def initialize(root)
|
106
|
-
@root = root
|
107
|
-
super()
|
108
|
-
Im.with_import(self) do
|
109
|
-
Im.toplevel_constants.each do |const|
|
110
|
-
self.const_set(const, Object.const_get(const))
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def inspect
|
116
|
-
@inspect ||= "<#Im::Import root: #{@root}>"
|
117
|
-
end
|
118
|
-
|
119
|
-
def const_added(name)
|
120
|
-
path = const_source_location(name)[0]
|
121
|
-
value = const_get(name, false)
|
122
|
-
Im.registry[path] ||= Require.new(path, self)
|
123
|
-
Im.registry[path].defined_constants[name] ||= value
|
124
|
-
super
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
Require = Struct.new(:path, :import, :defined_constants, :requires) do
|
129
|
-
def initialize(path, import, defined_constants = {}, requires = [])
|
130
|
-
super
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
4
|
+
require_relative "im/const_path"
|
5
|
+
require_relative "im/internal"
|
6
|
+
require_relative "im/loader"
|
7
|
+
require_relative "im/gem_loader"
|
8
|
+
require_relative "im/registry"
|
9
|
+
require_relative "im/explicit_namespace"
|
10
|
+
require_relative "im/module_const_added"
|
11
|
+
require_relative "im/inflector"
|
12
|
+
require_relative "im/gem_inflector"
|
13
|
+
require_relative "im/kernel"
|
14
|
+
require_relative "im/error"
|
15
|
+
require_relative "im/version"
|
16
|
+
|
17
|
+
extend Im::ConstPath
|
18
|
+
|
19
|
+
# @sig (String) -> Im::Loader?
|
134
20
|
def import(path)
|
135
|
-
|
136
|
-
|
137
|
-
raise LoadError, "import can only import ruby files" unless resolved[0] == :rb
|
138
|
-
else
|
139
|
-
raise LoadError, "cannot load such file -- #{path}"
|
140
|
-
end
|
141
|
-
|
142
|
-
required = Im.registry.fetch(resolved_path) do
|
143
|
-
# handle autoload within import
|
144
|
-
return nil if $LOADED_FEATURES.include?(resolved_path)
|
145
|
-
|
146
|
-
$LOADED_FEATURES << resolved_path
|
147
|
-
|
148
|
-
import = Im.current_import || Import.new(path)
|
149
|
-
(Im.registry[resolved_path] ||= Require.new(resolved_path, import)).tap do
|
150
|
-
Im.with_import(import) do
|
151
|
-
load resolved_path, import
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
Im.import_constants(required, Im.current_imports)
|
157
|
-
|
158
|
-
required&.import
|
21
|
+
_, feature_path = $:.resolve_feature_path(path)
|
22
|
+
Registry.loader_for(feature_path) if feature_path
|
159
23
|
end
|
160
24
|
|
161
|
-
@tracer = TracePoint.new(:class) do |event|
|
162
|
-
next unless (name = event.self.name&.to_sym)
|
163
|
-
next if Im.toplevel_constants.include?(name)
|
164
|
-
|
165
|
-
# We don't want to track classes defined under singleton classes, like
|
166
|
-
# this:
|
167
|
-
#
|
168
|
-
# class Foo
|
169
|
-
# class << self
|
170
|
-
# class Bar
|
171
|
-
# end
|
172
|
-
# end
|
173
|
-
# end
|
174
|
-
#
|
175
|
-
# Here, `class Bar` will trigger a TracePoint event, and because of the
|
176
|
-
# Ruby patch `name` will return "Bar", but this is not actually a class we
|
177
|
-
# need to alias in imports, so we can safely skip it. The only way I've
|
178
|
-
# found to do that though is to evaluate `Module.nesting` from the event's
|
179
|
-
# binding. This is weird, but it works!
|
180
|
-
#
|
181
|
-
next if event.binding.eval("Module.nesting").any?(&:singleton_class?)
|
182
|
-
|
183
|
-
if resolved = $:.resolve_feature_path(event.path)
|
184
|
-
resolved_path = resolved[1]
|
185
|
-
Im.registry[resolved_path] ||= Require.new(resolved_path, Im.current_import)
|
186
|
-
Im.registry[resolved_path].defined_constants[name] = event.self
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
require "im/module"
|
191
|
-
|
192
25
|
extend self
|
193
26
|
end
|
metadata
CHANGED
@@ -1,84 +1,48 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: im
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Salzberg
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
-
|
14
|
-
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '13.0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '13.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake-compiler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '3.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '3.0'
|
55
|
-
description: Import code without side-effects.
|
56
|
-
email:
|
57
|
-
- chris@dejimata.com
|
11
|
+
date: 2023-01-28 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: " Im is a thread-safe code loader for anonymous-rooted namespaces.\n"
|
14
|
+
email: chris@dejimata.com
|
58
15
|
executables: []
|
59
16
|
extensions: []
|
60
17
|
extra_rdoc_files: []
|
61
18
|
files:
|
62
|
-
-
|
63
|
-
- Gemfile
|
64
|
-
- Gemfile.lock
|
65
|
-
- LICENSE.txt
|
19
|
+
- MIT-LICENSE
|
66
20
|
- README.md
|
67
|
-
- Rakefile
|
68
21
|
- lib/im.rb
|
22
|
+
- lib/im/const_path.rb
|
23
|
+
- lib/im/error.rb
|
24
|
+
- lib/im/explicit_namespace.rb
|
25
|
+
- lib/im/gem_inflector.rb
|
26
|
+
- lib/im/gem_loader.rb
|
27
|
+
- lib/im/inflector.rb
|
28
|
+
- lib/im/internal.rb
|
69
29
|
- lib/im/kernel.rb
|
70
|
-
- lib/im/
|
71
|
-
- lib/im/
|
30
|
+
- lib/im/loader.rb
|
31
|
+
- lib/im/loader/callbacks.rb
|
32
|
+
- lib/im/loader/config.rb
|
33
|
+
- lib/im/loader/eager_load.rb
|
34
|
+
- lib/im/loader/helpers.rb
|
35
|
+
- lib/im/module_const_added.rb
|
36
|
+
- lib/im/registry.rb
|
72
37
|
- lib/im/version.rb
|
73
38
|
homepage: https://github.com/shioyama/im
|
74
39
|
licenses:
|
75
40
|
- MIT
|
76
41
|
metadata:
|
77
42
|
homepage_uri: https://github.com/shioyama/im
|
43
|
+
changelog_uri: https://github.com/shioyama/im/blob/master/CHANGELOG.md
|
78
44
|
source_code_uri: https://github.com/shioyama/im
|
79
45
|
bug_tracker_uri: https://github.com/shioyama/im/issues
|
80
|
-
changelog_uri: https://github.com/shioyama/im/CHANGELOG.md
|
81
|
-
rubygems_mfa_required: 'true'
|
82
46
|
post_install_message:
|
83
47
|
rdoc_options: []
|
84
48
|
require_paths:
|
@@ -87,15 +51,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
51
|
requirements:
|
88
52
|
- - ">="
|
89
53
|
- !ruby/object:Gem::Version
|
90
|
-
version: 3.
|
54
|
+
version: '3.2'
|
91
55
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
56
|
requirements:
|
93
57
|
- - ">="
|
94
58
|
- !ruby/object:Gem::Version
|
95
59
|
version: '0'
|
96
60
|
requirements: []
|
97
|
-
rubygems_version: 3.
|
61
|
+
rubygems_version: 3.4.0.dev
|
98
62
|
signing_key:
|
99
63
|
specification_version: 4
|
100
|
-
summary:
|
64
|
+
summary: Multiverse autoloader
|
101
65
|
test_files: []
|
data/CHANGELOG.md
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
## [Unreleased]
|
2
|
-
|
3
|
-
## [0.1.6] - 2022-10-03
|
4
|
-
- Remove `Object.const_missing` patch (Ruby patch now handles dynamic toplevel
|
5
|
-
references)
|
6
|
-
|
7
|
-
## [0.1.5] - 2022-09-22
|
8
|
-
- Rename Im::Dependency -> Im::Require
|
9
|
-
- Handle dynamic requires (require called from method body after file has been imported)
|
10
|
-
- Refactor: move require/autoload patch logic to Im handler methods
|
11
|
-
|
12
|
-
## [0.1.4] - 2022-09-19
|
13
|
-
- Correctly assign constants imported via recursive requires
|
14
|
-
|
15
|
-
## [0.1.3] - 2022-09-16
|
16
|
-
- Fix gemspec
|
17
|
-
|
18
|
-
## [0.1.1] - 2022-09-16
|
19
|
-
|
20
|
-
- Fix TracePoint event
|
21
|
-
- Simplify import inspect
|
22
|
-
- Remove unnecessary Kernel#autoload patch
|
23
|
-
- Encode comprehensive list of top-level constants
|
24
|
-
|
25
|
-
## [0.1.0] - 2022-09-15
|
26
|
-
|
27
|
-
- Initial release, requires patched version of Ruby.
|
28
|
-
|
29
|
-
## [0.0.1] - 2022-07-13
|
30
|
-
|
31
|
-
- Stub
|
data/Gemfile
DELETED
data/Gemfile.lock
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
im (0.1.6)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
diff-lcs (1.5.0)
|
10
|
-
rake (13.0.6)
|
11
|
-
rake-compiler (1.2.0)
|
12
|
-
rake
|
13
|
-
rspec (3.11.0)
|
14
|
-
rspec-core (~> 3.11.0)
|
15
|
-
rspec-expectations (~> 3.11.0)
|
16
|
-
rspec-mocks (~> 3.11.0)
|
17
|
-
rspec-core (3.11.0)
|
18
|
-
rspec-support (~> 3.11.0)
|
19
|
-
rspec-expectations (3.11.0)
|
20
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
21
|
-
rspec-support (~> 3.11.0)
|
22
|
-
rspec-mocks (3.11.1)
|
23
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
24
|
-
rspec-support (~> 3.11.0)
|
25
|
-
rspec-support (3.11.0)
|
26
|
-
|
27
|
-
PLATFORMS
|
28
|
-
x86_64-linux
|
29
|
-
|
30
|
-
DEPENDENCIES
|
31
|
-
im!
|
32
|
-
rake (~> 13.0)
|
33
|
-
rake-compiler
|
34
|
-
rspec (~> 3.0)
|
35
|
-
|
36
|
-
BUNDLED WITH
|
37
|
-
2.3.18
|
data/LICENSE.txt
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
The MIT License (MIT)
|
2
|
-
|
3
|
-
Copyright (c) 2022 Chris Salzberg
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in
|
13
|
-
all copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
THE SOFTWARE.
|
data/Rakefile
DELETED