named_imports 0.1.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97be320b89b4ac114bed6fb578408e92469e03ad329a9039f5cd1f3ede527d7d
4
- data.tar.gz: 746036f1c888ea3c5ba714449cbe73619c510c4c0cc9f0813c63376fdad446ef
3
+ metadata.gz: cfc9a0d0b8e5f11fc766551ff061c718b590fe78c8a0d389731899953a38aadc
4
+ data.tar.gz: 11e50d338348cc168e96fc314bc41981407c3483a5d78db814ed4bb61cd5543e
5
5
  SHA512:
6
- metadata.gz: 473f6a20a5a5c2a8a6161750c4137a2ba5ff1b0bed490de4193fe89a0b50216ee7e59a975109f65ebc2113808bc646cc837cb16749a62284a8f06b19ebccdabd
7
- data.tar.gz: 915c2555d3e2370d52388b8954bd254c4511f1e05c51e73687f3dacd24ddf19dc77678a53160f80d7e1b0a68c7869bf8663f52fd5e3f93f0208835d115cb3cd6
6
+ metadata.gz: 01572a85739777dca2eb49050098e9e07ca7c93f7ba7a5716442bc36690e6a6c296b26ed2a1c8b473f68c6ea4097ae67d860a9850a19dadeb58b60b61ef617a7
7
+ data.tar.gz: 0074367a1fddfb4b935026e0604ca80555d1bcaf6e6cf5c574dfbf9865ccac6e6ac8462271cc27218c30955300cfb80ad4cd08705d5169c34ca43b2860edb80a
data/README.md CHANGED
@@ -86,8 +86,6 @@ Baz.some_str
86
86
  #=> "hi"
87
87
  ```
88
88
 
89
- > **Note:** Currently, non-specified constants defined in the imported file _will_ be available _after_ you've used one (or more) of the constants you specified in the import statement. Working on it!
90
-
91
89
  You can import multiple constants as well, by separating them with a semicolon in the `import` block:
92
90
 
93
91
  ```rb
@@ -124,7 +122,9 @@ Bop.some_hash
124
122
  - [x] multiple constant imports
125
123
  - [ ] top-level function imports
126
124
  - [x] namespace should not be polluted with non-specified constants (before the specified import is referenced/used)
127
- - [ ] namespace should not be polluted with non-specified constants (after the specified import is referenced/used)
125
+ - [x] namespace should not be polluted with non-specified constants (after the specified import is referenced/used)
126
+ - [ ] namespace of child imports should not be polluted with constants from the parent's scope
127
+ - [ ] cached imports so constants are always reused (as opposed to being redefined in a new anonymous module)
128
128
 
129
129
  ## Development
130
130
 
data/lib/named_imports.rb CHANGED
@@ -6,19 +6,32 @@ module NamedImports
6
6
  class Error < StandardError; end
7
7
 
8
8
  class << self
9
- def from(path, constants)
10
- ext = %r{[^/]+\.[^/]+$}.match?(path) ? "" : ".rb"
11
- path_with_ext = "#{path}#{ext}"
12
- caller_dir = File.dirname(caller(2..2).first)
13
- full_path = File.expand_path(path_with_ext, caller_dir)
14
-
15
- constants.each do |constant_name|
16
- Object.send(:remove_const, constant_name.to_sym)
17
- Object.autoload constant_name.to_sym, full_path
9
+ def from(path, constants, context = Object)
10
+ path_where_import_occurs = caller(2..2).first
11
+ full_path = full_path_for_import(path, path_where_import_occurs)
12
+
13
+ File.open(full_path, "r") do |file|
14
+ file_content = file.read
15
+ anon_mod = Module.new
16
+
17
+ anon_mod.define_singleton_method(:from) do |path, constants|
18
+ NamedImports.from(path, constants, anon_mod)
19
+ end
20
+
21
+ anon_mod.define_singleton_method(:import) do |&block|
22
+ NamedImports.import(&block)
23
+ end
24
+
25
+ anon_mod.class_eval(file_content, full_path)
26
+
27
+ constants.each do |constant_name|
28
+ context.send(:remove_const, constant_name) if context.const_defined?(constant_name, false)
29
+ context.const_set(constant_name, anon_mod.const_get(constant_name))
30
+ end
18
31
  end
19
32
  end
20
33
 
21
- def import
34
+ def import(context = Object)
22
35
  constants = []
23
36
 
24
37
  begin
@@ -26,12 +39,18 @@ module NamedImports
26
39
  rescue NameError => e
27
40
  raise e unless /uninitialized constant /.match?(e.message)
28
41
 
29
- constant_name = e.message.gsub(/uninitialized constant /, '').to_s
42
+ constant_match = e.message.match(/uninitialized constant (?:#<Module:[^>]+>::)?(\w*(?:::\w+)*)$/)
43
+ constant_name = constant_match && constant_match[1]
44
+
45
+ if constant_name.nil?
46
+ raise NameError, "unable to import constant: #{e.message.gsub(/uninitialized constant /, '')}"
47
+ end
48
+
30
49
  already_there = constants.include?(constant_name)
31
50
 
32
51
  unless already_there
33
52
  constants << constant_name
34
- Object.const_set(constant_name, nil)
53
+ context.const_set(constant_name, nil)
35
54
  end
36
55
 
37
56
  retry
@@ -39,13 +58,22 @@ module NamedImports
39
58
 
40
59
  constants
41
60
  end
61
+
62
+ private
63
+
64
+ def full_path_for_import(imported_path, importer_path)
65
+ ext = %r{[^/]+\.[^/]+$}.match?(imported_path) ? "" : ".rb"
66
+ imported_path_with_ext = "#{imported_path}#{ext}"
67
+ importer_dir = File.dirname(importer_path)
68
+ File.expand_path(imported_path_with_ext, importer_dir)
69
+ end
42
70
  end
43
71
 
44
- Kernel.define_method(:from) do |path, constants|
72
+ Object.define_method(:from) do |path, constants|
45
73
  NamedImports.from(path, constants)
46
74
  end
47
75
 
48
- Kernel.define_method(:import) do |&block|
76
+ Object.define_method(:import) do |&block|
49
77
  NamedImports.import(&block)
50
78
  end
51
79
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NamedImports
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -37,4 +37,5 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency "rubocop-rake", "~> 0.5"
38
38
  spec.add_development_dependency "rubocop-rspec", "~> 2.2"
39
39
  spec.add_development_dependency "solargraph"
40
+ spec.add_development_dependency "pry"
40
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: named_imports
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keegan Leitz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-17 00:00:00.000000000 Z
11
+ date: 2021-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  description: Stop asking where that thing came from.
126
140
  email:
127
141
  - kjleitz@gmail.com