requirium 0.0.5 → 0.0.6

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
  SHA1:
3
- metadata.gz: eaeb02dd4c979c7c0d610fca588f890f22bbb40d
4
- data.tar.gz: d7a7acb203652154316a9f79ad91a380d32493a0
3
+ metadata.gz: cc6d1b42fef265d9d746f66b27c0c4757e2859bb
4
+ data.tar.gz: 0e85c2d1df41508261491d1894dc01eb79d41e14
5
5
  SHA512:
6
- metadata.gz: ff0e9ba46cd44ca282958b86e450d33d3b666c0a7307e96a5ede7290ce8299ca57a6834e452dd051fc142f063a3a45bf01c2d3d5458fdd323b952cdde1dbc7cf
7
- data.tar.gz: 2f5b961015812a391151513c79ff687c300f4093da11a34ac79fcd18839c27e3dbe62b005570e58e5ce6b39d9c142f24a5292cf6e82d6ece7fcb9050d2881447
6
+ metadata.gz: cb6e12b95075241f395a359608dfb8063a4f803d2dadbe140003daff2a7e4ce29a52d25feacb7697d1379979800072e35d4a81ee6109e5a1333b3d54636e5987
7
+ data.tar.gz: 09bf328c61e8801b0df81bcdc23dee2650317917bd095a82d6ea6338ebaa68526cecab94c1c5c71034587ff1509b825bbf1f99b9a86456442ab1b9fcc8759a3e
@@ -1,28 +1,61 @@
1
- class Requirium::ConstInfo
2
- attr_accessor :mod, :sym, :error, :value
1
+ module Requirium
2
+ class ConstInfo
3
+ attr_accessor :mod, :sym, :nesting, :error, :value
3
4
 
4
- def initialize(mod, sym)
5
- @mod, @sym, @cond, @mutex = mod, sym, ConditionVariable.new, Mutex.new
6
- end
5
+ def initialize(mod, sym, nesting)
6
+ @mod, @sym, @nesting, @cond, @mutex = mod, sym, nesting, ConditionVariable.new, Mutex.new
7
+ end
7
8
 
8
- def has_value?
9
- !!(defined? @value)
10
- end
9
+ def has_value?
10
+ !!(defined? @value)
11
+ end
11
12
 
12
- def internal_load
13
- has, value = mod.send(:internal_load, sym)
14
- @value = value if has
15
- nil
16
- end
13
+ def internal_load
14
+ has, value = mod.send(:internal_load, self)
15
+ @value = value if has
16
+ nil
17
+ end
17
18
 
18
- def ready!
19
- @ready = true
20
- @mutex.synchronize { @cond.signal }
21
- nil
22
- end
19
+ def lookup_list
20
+ return @nesting | @mod.ancestors if @nesting # always returns for mri
21
+
22
+ # hacky fallback for jruby, rubinius, etc...
23
+
24
+ # singleton classes don't have a name, but the base class is the first from the ancestors
25
+
26
+ case
27
+ # usual class
28
+ when @mod.name
29
+ split(@mod.name) | @mod.ancestors
30
+
31
+ # singleton
32
+ when @mod.ancestors.first != @mod
33
+ mod = ObjectSpace.each_object(@mod).first
34
+ split(mod.name) | mod.ancestors
35
+
36
+ # anonymous class
37
+ else
38
+ mod.ancestors
39
+ end
40
+
41
+ end
42
+
43
+ def ready!
44
+ @ready = true
45
+ @mutex.synchronize { @cond.signal }
46
+ nil
47
+ end
48
+
49
+ def wait_ready
50
+ @mutex.synchronize { until @ready; @cond.wait(@mutex) end }
51
+ nil
52
+ end
53
+
54
+ private
23
55
 
24
- def wait_ready
25
- @mutex.synchronize { until @ready; @cond.wait(@mutex) end }
26
- nil
56
+ def split(name)
57
+ return [] unless name
58
+ name.split('::').reduce([]) { |a, n| a << (a.last || Object).const_get(n) }.reverse!
59
+ end
27
60
  end
28
61
  end
@@ -1,19 +1,21 @@
1
1
  require_relative 'require_loader'
2
2
 
3
- class Requirium::LoadLoader < Requirium::RequireLoader
3
+ module Requirium
4
+ class LoadLoader < RequireLoader
4
5
 
5
- private
6
+ private
6
7
 
7
- def clean_paths(paths, dirname)
8
- paths = super
8
+ def clean_paths(paths, dirname)
9
+ paths = super
9
10
 
10
- # append possible suffix
11
- paths.map! { |p| Dir[*Gem.suffixes.map { |e| p + e }].first }.compact!
11
+ # append possible suffix
12
+ paths.map! { |p| Dir[*Gem.suffixes.map { |e| p + e }].first }.compact!
12
13
 
13
- paths
14
- end
14
+ paths
15
+ end
15
16
 
16
- def method
17
- :load
17
+ def method
18
+ :load
19
+ end
18
20
  end
19
21
  end
@@ -1,31 +1,33 @@
1
- class Requirium::RequireLoader
2
- attr_reader :sym
1
+ module Requirium
2
+ class RequireLoader
3
+ attr_reader :sym
3
4
 
4
- def initialize(sym, paths, dirname = nil)
5
- @sym = sym
6
- @paths = clean_paths(paths, dirname)
7
- end
5
+ def initialize(sym, paths, dirname = nil)
6
+ @sym = sym
7
+ @paths = clean_paths(paths, dirname)
8
+ end
8
9
 
9
- def call(mod)
10
- @paths.each { |filename| mod.send(method, filename) }
11
- nil
12
- end
10
+ def call(mod)
11
+ @paths.each { |filename| mod.send(method, filename) }
12
+ nil
13
+ end
13
14
 
14
- private
15
+ private
15
16
 
16
- def clean_paths(paths, dirname)
17
- paths = [*paths]
18
- paths = [sym.to_s.snakecase] if paths.empty?
17
+ def clean_paths(paths, dirname)
18
+ paths = [*paths]
19
+ paths = [sym.to_s.snakecase] if paths.empty?
19
20
 
20
- if dirname
21
- dirname = Pathname(dirname)
22
- paths.map! { |path| (dirname + path).to_s }
23
- end
21
+ if dirname
22
+ dirname = Pathname(dirname)
23
+ paths.map! { |path| (dirname + path).to_s }
24
+ end
24
25
 
25
- paths
26
- end
26
+ paths
27
+ end
27
28
 
28
- def method
29
- :require
29
+ def method
30
+ :require
31
+ end
30
32
  end
31
33
  end
@@ -1,3 +1,4 @@
1
+ require 'continuation'
1
2
  require 'thread'
2
3
  require 'pathname'
3
4
  require 'facets/string/snakecase'
@@ -50,20 +51,12 @@ module Requirium
50
51
  attr_reader :loader_thread, :queue
51
52
  end
52
53
 
53
- def autoload(*args)
54
- add_loader LoadLoader, args
55
- end
56
-
57
- def autoload_relative(*args)
58
- add_loader LoadLoader, args, File.dirname(caller(1, 1)[0][/^(.+):\d+:in `.+'$/, 1])
59
- end
60
-
61
- def autorequire(*args)
62
- add_loader RequireLoader, args
63
- end
64
-
65
- def autorequire_relative(*args)
66
- add_loader RequireLoader, args, File.dirname(caller(1, 1)[0][/^(.+):\d+:in `.+'$/, 1])
54
+ [:load, :require].each do |name|
55
+ type = const_get("#{name.capitalize}Loader")
56
+ define_method("auto#{name}", ->(*args) { add_loader type, args })
57
+ define_method("auto#{name}_relative", ->(*args) do
58
+ add_loader type, args, File.dirname(caller_locations(1, 1).first.path)
59
+ end)
67
60
  end
68
61
 
69
62
  #def const_defined?(*args)
@@ -71,13 +64,21 @@ module Requirium
71
64
  #end
72
65
 
73
66
  def const_missing(sym)
67
+ # if mri, use binding nesting
68
+ nesting = nil
69
+ if Requirium.mri?
70
+ return unless nesting = caller_nesting
71
+ end
72
+
73
+ info = ConstInfo.new(self, sym, nesting)
74
+
74
75
  if Thread.current == Requirium.loader_thread
75
76
  # this avoids deadlocks. it uses the current loading to load the remaining dependencies
76
- has, value = internal_load(sym)
77
+ has, value = internal_load(info)
77
78
  return has ? value : super
78
79
  end
79
80
 
80
- Requirium.queue.push(info = ConstInfo.new(self, sym))
81
+ Requirium.queue.push(info)
81
82
  info.wait_ready
82
83
  raise info.error if info.error
83
84
  info.has_value? ? info.value : super
@@ -85,16 +86,37 @@ module Requirium
85
86
 
86
87
  private
87
88
 
88
- def add_loader(method, args, dirname = nil)
89
+ def add_loader(type, args, dirname = nil)
89
90
  with_args(args) do |sym, paths|
90
- load_list { |l| l[sym.to_s] = method.new(sym, paths, dirname) }
91
+ load_list { |l| l[sym.to_s] = type.new(sym, paths, dirname) }
91
92
  end
92
93
  end
93
94
 
94
- def internal_load(sym)
95
- lookup_list.find do |klass|
96
- klass.send(:try_load, sym) if klass.singleton_class.include?(Requirium)
97
- return [true, klass.const_get(sym)] if klass.const_defined?(sym)
95
+ def caller_nesting
96
+ cc = nil
97
+ nst = nil
98
+ count = 0
99
+
100
+ t = Thread.current
101
+
102
+ set_trace_func(lambda do |event, _, _, _, binding, _|
103
+ if Thread.current == t
104
+ if count == 2
105
+ set_trace_func nil
106
+ cc.call(nst = eval('Module.nesting', binding))
107
+ elsif event == 'return'
108
+ count += 1
109
+ end
110
+ end
111
+ end)
112
+
113
+ callcc { |cont| cc = cont } && nst
114
+ end
115
+
116
+ def internal_load(info)
117
+ info.lookup_list.find do |klass|
118
+ klass.send(:try_load, info.sym) if klass.singleton_class.include?(Requirium)
119
+ return [true, klass.const_get(info.sym)] if klass.const_defined?(info.sym)
98
120
  end
99
121
 
100
122
  [false, nil]
@@ -128,11 +150,7 @@ module Requirium
128
150
  nil
129
151
  end
130
152
 
131
- def lookup_list
132
- list = name.split('::').reduce([Object]) { |a, n| a << a.last.const_get(n) }.reverse!
133
- list.push(*ancestors)
134
- list.uniq!
135
- list
153
+ def self.mri?
154
+ (!defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby') && RUBY_DESCRIPTION !~ /Enterprise/
136
155
  end
137
-
138
156
  end
@@ -1,3 +1,3 @@
1
1
  module Requirium
2
- VERSION = '0.0.5'.freeze
2
+ VERSION = '0.0.6'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: requirium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - SilverPhoenix99
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-15 00:00:00.000000000 Z
11
+ date: 2014-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: facets
@@ -31,12 +31,12 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - README.md
34
35
  - lib/const_info.rb
35
36
  - lib/load_loader.rb
36
37
  - lib/require_loader.rb
37
38
  - lib/requirium.rb
38
39
  - lib/version.rb
39
- - README.md
40
40
  homepage: https://github.com/SilverPhoenix99/requirium
41
41
  licenses:
42
42
  - MIT
@@ -46,7 +46,7 @@ post_install_message: |
46
46
  Thank you for choosing Requirium.
47
47
 
48
48
  ==========================================================================
49
- If you find any bugs, please report them on
49
+ If you find any bugs, please report them at
50
50
  https://github.com/SilverPhoenix99/requirium/issues
51
51
 
52
52
  +----------------------------------------------------------------------------+
@@ -65,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
65
  version: '0'
66
66
  requirements: []
67
67
  rubyforge_project:
68
- rubygems_version: 2.0.14
68
+ rubygems_version: 2.3.0
69
69
  signing_key:
70
70
  specification_version: 4
71
71
  summary: An autoload alternative