requirium 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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