modules 0.1.1 → 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,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f01db94c8f224ccc34c29f46d5162323176f527e
4
- data.tar.gz: 0a8132753316ea571e714bdef63ff3f12d3040ea
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MmNjMjU5YTk0YjRjNWE4ZDY3ZTJjNTNkZWUxNThjODk3MWM1MGZlZg==
5
+ data.tar.gz: !binary |-
6
+ YTE2OWIyNmUwNjk2YmIxMDIxMDM4ZDdhYmI0ODlhOGFiZGQxNGIyZQ==
5
7
  SHA512:
6
- metadata.gz: 12a947436ab67b46aa4decf773a1286eee0fc7c5506b1fc6c9df0fdc59f7eea8d253a6c1b2683df6baad558adc289f8b9c4d35a748541e6e02e7dca346201540
7
- data.tar.gz: 25e1419b2970e4625bd64025a335d2bf7d0bf93cf5dcfa930f6aa2d54f9263812a3a5461d7e4da6bc33a87f1415e3418349322d31e260d79ea5be8cf8598c006
8
+ metadata.gz: !binary |-
9
+ YmQzYTIyZjI3MDM5YzdmZjJmNGFhYmVmNGYxM2RjOWM5YWRmYTgzMTEzNTY1
10
+ MDcxMjhkMTdiNDNkZWM1MTkzZmI2NTU5NTg4NWNjMDk3YjA3NjdkYTg2ZTMw
11
+ ZDFjZjBiZWI0NTVjNTYwNTZjMGJmMWU1YTg3MzdhNWVjMjNhMjU=
12
+ data.tar.gz: !binary |-
13
+ ODhiZTFkZDUxMjExMWMxYmJjNmQ1ZTM3OTI2Zjc5NGU0YzI5OTdhZmYyNmUx
14
+ ODk5ZmJkNjExNWYyOWYwMjJkMjAxZTE2ZjNhYzEwM2E1ZjQ0YzQzYTc3YmE3
15
+ MTg0NjM3OGUxYzBjZjBjNDQyNmQ5OGM4MGQ4M2M0NTY2MTI4ODI=
data/lib/debug.rb ADDED
@@ -0,0 +1,13 @@
1
+ module Debug
2
+ @enabled = false
3
+
4
+ def self.enable(value)
5
+ @enabled = !!value
6
+ end
7
+
8
+ def self.debug(topic)
9
+ lambda do |msg|
10
+ puts "[#{topic}] #{msg}" if @enabled
11
+ end
12
+ end
13
+ end
data/lib/global.rb CHANGED
@@ -1,8 +1,13 @@
1
1
  require_relative './loader'
2
2
 
3
3
  class Object
4
- def export
5
- value = yield
4
+ def export(name=nil, value=nil)
5
+ if name.nil?
6
+ value = yield
7
+ else
8
+ value = {name => value}
9
+ end
10
+
6
11
  Loader.export(value)
7
12
  end
8
13
 
data/lib/interop.rb CHANGED
@@ -1,20 +1,27 @@
1
+ require 'set'
2
+
3
+ require_relative './debug'
4
+
1
5
  module Interop
6
+ DEBUG = Debug.debug(File.basename(__FILE__))
7
+
8
+ # (Hash) map from module identifier to resolved module
2
9
  @cache = {}
3
10
 
4
11
  def self.import(id)
5
12
  if @cache.include?(id)
6
- puts "Cache hit #{id}"
13
+ DEBUG.call "Cache hit #{id}"
7
14
  return @cache[id]
8
15
  end
9
16
 
10
- puts "Load #{id}"
17
+ DEBUG.call "Load #{id}"
11
18
  snapshot = Module.constants
12
19
  require id
13
20
  cleanly_load(Module.constants - snapshot)
14
21
  end
15
22
 
16
23
  def self.cleanly_load(targets)
17
- puts "Package definitions #{targets}"
24
+ DEBUG.call "Package definitions #{targets}"
18
25
  result = wrap_constants(targets)
19
26
  result.each_pair do |key, value|
20
27
  Object.send(:remove_const, key.to_sym) unless key.include?('::')
@@ -23,7 +30,7 @@ module Interop
23
30
  result
24
31
  end
25
32
 
26
- def self.wrap_constants(new, result={})
33
+ def self.wrap_constants(new, result={}, visited=Set.new)
27
34
  if new.length == 0
28
35
  return result
29
36
  end
@@ -35,12 +42,18 @@ module Interop
35
42
  end
36
43
 
37
44
  if const.respond_to? :constants
38
- # TODO(ari): Handle circular references!
39
- children = const.constants.map {|child| "#{str}::#{child.to_s}"}
45
+ children = const
46
+ .constants
47
+ .reject {|element| visited.include?(element)}
48
+ .map {|child|
49
+ visited.add(child)
50
+ "#{str}::#{child.to_s}"
51
+ }
52
+
40
53
  new += children
41
54
  end
42
55
 
43
56
  result[str] = const.class == Module ? Class.new.extend(const) : const
44
- return wrap_constants(new, result)
57
+ return wrap_constants(new, result, visited)
45
58
  end
46
59
  end
data/lib/loader.rb CHANGED
@@ -1,6 +1,9 @@
1
+ require_relative './debug'
1
2
  require_relative './interop'
2
3
 
3
4
  module Loader
5
+ DEBUG = Debug.debug(File.basename(__FILE__))
6
+
4
7
  # (String) root path for module resolution
5
8
  @basepath = '/'
6
9
 
@@ -11,12 +14,17 @@ module Loader
11
14
  @path = nil
12
15
 
13
16
  def self.export(value)
14
- @cache[@path] = value
17
+ if @cache.include?(@path) && value.class == Hash
18
+ # Special handling to enable multiple exports
19
+ @cache[@path] = @cache[@path].merge(value)
20
+ else
21
+ @cache[@path] = value
22
+ end
15
23
  end
16
24
 
17
25
  def self.import(id, type=nil)
18
26
  chr = id[0]
19
- if type == 'interop' || (type != 'internal' && !['/', '.'].include?(chr))
27
+ if type == 'interop'
20
28
  return Interop.import(id)
21
29
  end
22
30
 
@@ -29,18 +37,27 @@ module Loader
29
37
  end
30
38
 
31
39
  @path = File.expand_path(raw)
32
- if !@cache.include?(@path)
33
- id = @path.end_with?('.rb') ? @path : "#{@path}.rb"
34
- Kernel.load(id, true)
40
+ filepath = @path.end_with?('.rb') ? @path : "#{@path}.rb"
41
+ exists = File.exist?(filepath)
42
+ if type == 'internal' && !exists
43
+ raise "Could not resolve local module at #{@path}"
44
+ end
45
+
46
+ if exists
47
+ # Prefer loading local module since we found it.
48
+ Kernel.load(filepath, true) unless @cache.include?(@path)
49
+ result = @cache[@path]
50
+ else
51
+ # Failover to external load.
52
+ result = Interop.import(id)
35
53
  end
36
54
 
37
- result = @cache[@path]
38
55
  @path = prev
39
56
  result
40
57
  end
41
58
 
42
59
  def self.set_basepath(basepath)
43
- puts "Set basepath to #{basepath}"
60
+ DEBUG.call "Set basepath to #{basepath}"
44
61
  @basepath = basepath
45
62
  end
46
63
  end
data/lib/modules.rb CHANGED
@@ -1,7 +1,12 @@
1
+ require_relative './debug'
1
2
  require_relative './loader'
2
3
 
3
4
  module Modules
4
5
  def self.run(args, opts)
6
+ if opts.include?('debug')
7
+ Debug.enable(opts['debug'])
8
+ end
9
+
5
10
  file = args[0]
6
11
  abs = "#{Dir.pwd}/#{file}"
7
12
  Loader.set_basepath(File.dirname(abs))
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modules
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gareth (Ari) Aye
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-15 00:00:00.000000000 Z
11
+ date: 2017-01-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A Ruby module loader inspired by the semantics of js modules
14
14
  email: gareth@alumni.middlebury.edu
@@ -18,6 +18,7 @@ extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
20
  - bin/modules
21
+ - lib/debug.rb
21
22
  - lib/global.rb
22
23
  - lib/interop.rb
23
24
  - lib/loader.rb
@@ -26,24 +27,24 @@ homepage: https://github.com/lambdabaa/modules
26
27
  licenses:
27
28
  - MIT
28
29
  metadata: {}
29
- post_install_message:
30
+ post_install_message:
30
31
  rdoc_options: []
31
32
  require_paths:
32
33
  - lib
33
34
  required_ruby_version: !ruby/object:Gem::Requirement
34
35
  requirements:
35
- - - ">="
36
+ - - ! '>='
36
37
  - !ruby/object:Gem::Version
37
38
  version: '0'
38
39
  required_rubygems_version: !ruby/object:Gem::Requirement
39
40
  requirements:
40
- - - ">="
41
+ - - ! '>='
41
42
  - !ruby/object:Gem::Version
42
43
  version: '0'
43
44
  requirements: []
44
- rubyforge_project:
45
- rubygems_version: 2.4.8
46
- signing_key:
45
+ rubyforge_project:
46
+ rubygems_version: 2.6.8
47
+ signing_key:
47
48
  specification_version: 4
48
49
  summary: Port of js module loader to ruby
49
50
  test_files: []