requirium 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +67 -0
  3. data/lib/requirium.rb +135 -0
  4. metadata +69 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7dd79837d4d7b07b5b43a6e4bdb2b0d9282d3b98
4
+ data.tar.gz: 13ddcef5f0246ccbfcef8ded2a482d979fc7aedb
5
+ SHA512:
6
+ metadata.gz: 09e1b4dd928cdb25678789a5297e2294433a92a5d2a8e4f387cac139a6c9f8f5edca4e6039f24f505f62847f4a70960c885a392cbaf458724a8bf0602b0c6a4c
7
+ data.tar.gz: 87c1368019c3383bf822180a25054d93bccc5308095b20ddd4565cb096c151b6449964d1a41d7f9555f89216f28f55b7723e054123e045e2dd89bbf5ad9ab5e3
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # requirium
2
+
3
+ An autoload alternative for Ruby.
4
+
5
+ * https://github.com/SilverPhoenix99/requirium
6
+
7
+ ## INSTALL:
8
+
9
+ gem install requirium
10
+
11
+ ## DESCRIPTION:
12
+
13
+ Requirium offers advanced loading mechanisms, similar to Ruby's autoload and require.
14
+
15
+ `autoload` calls Ruby's `load`, while `autorequire` calls Ruby's `require` as expected, so they both search for files as Ruby does. But they do more than that, such as loading multiple files for a single constant, and batching multiple constants with a single call.
16
+
17
+ To use, simply extend the Requirium module and the loading methods will be available:
18
+
19
+ ```ruby
20
+ module M
21
+ extend Requirium
22
+
23
+ autoload :A # loads 'a' (camel case constant to snake case file name)
24
+ autoload :B, 'b', 'b1', 'dir/b2' # loads the 3 files
25
+ autoload A: nil, B: ['b', 'b1', 'dir/b2'] # joins the 2 previous options in a single call
26
+
27
+ autorequire :A # requires 'a'
28
+ autorequire :B, 'b', 'b1', 'dir/b2' # requires the 3 files
29
+ autorequire A: nil, B: ['b', 'b1', 'dir/b2'] # joins the 2 previous options in a single call
30
+
31
+ # theses next examples are similar to the previous ones,
32
+ # but they load relative to the current file
33
+
34
+ autoload_relative :X
35
+ autoload_relative :Y, 'y', 'y1', 'dir/y2'
36
+ autoload_relative X: nil, Y: ['y', 'y1', 'dir/y2']
37
+
38
+ autorequire_relative :X
39
+ autorequire_relative :Y, 'y', 'y1', 'dir/y2'
40
+ autorequire_relative X: nil, Y: ['y', 'y1', 'dir/y2']
41
+ end
42
+ ```
43
+
44
+ ## LICENSE:
45
+
46
+ (The MIT License)
47
+
48
+ Copyright © 2014 Pedro Pinto
49
+
50
+ Permission is hereby granted, free of charge, to any person obtaining
51
+ a copy of this software and associated documentation files (the
52
+ 'Software'), to deal in the Software without restriction, including
53
+ without limitation the rights to use, copy, modify, merge, publish,
54
+ distribute, sublicense, and/or sell copies of the Software, and to
55
+ permit persons to whom the Software is furnished to do so, subject to
56
+ the following conditions:
57
+
58
+ The above copyright notice and this permission notice shall be
59
+ included in all copies or substantial portions of the Software.
60
+
61
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
62
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
63
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
64
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
65
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
66
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
67
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/lib/requirium.rb ADDED
@@ -0,0 +1,135 @@
1
+ require 'thread'
2
+ require 'pathname'
3
+ require 'facets/string/snakecase'
4
+
5
+ #Automatically calls <code>Kernel#load</code> or <code>Kernel#require</code> on first use.
6
+ #Example usage:
7
+ #
8
+ # module M
9
+ # extend Requirium
10
+ #
11
+ # autoload :A
12
+ # autoload :B, 'b', 'b1', 'b2'
13
+ # autoload A: nil, B: ['b', 'b1', 'b2']
14
+ # autoload_relative :X
15
+ # autoload_relative :Y, 'y', 'y1', 'y2'
16
+ # autoload_relative X: nil, Y: ['y', 'y1', 'y2']
17
+ #
18
+ # autorequire :A
19
+ # autorequire :B, 'b', 'b1', 'b2'
20
+ # autorequire A: nil, B: ['b', 'b1', 'b2']
21
+ # autorequire_relative :X
22
+ # autorequire_relative :Y, 'y', 'y1', 'y2'
23
+ # autorequire_relative X: nil, Y: ['y', 'y1', 'y2']
24
+ # end
25
+ module Requirium
26
+ VERSION = '0.0.1'.freeze
27
+
28
+ EXTENSIONS = "{#{Gem.suffixes.join(',')}}".freeze
29
+
30
+ class CondVar < ConditionVariable
31
+ def mutex
32
+ @mutex ||= Mutex.new
33
+ end
34
+
35
+ def ready!
36
+ @ready = true
37
+ mutex.synchronize { signal }
38
+ nil
39
+ end
40
+
41
+ def wait_ready
42
+ mutex.synchronize { until @ready; wait(mutex) end }
43
+ nil
44
+ end
45
+ end
46
+
47
+ @queue = Queue.new
48
+ @loader_thread = Thread.new do
49
+ loop do
50
+ mod, sym, cond = @queue.pop
51
+ begin
52
+ mod.send(:internal_load, sym)
53
+ rescue ScriptError => e
54
+ $stderr.puts e
55
+ rescue => e
56
+ $stderr.puts e
57
+ end
58
+ cond.ready!
59
+ end
60
+ end
61
+
62
+ class << self
63
+ attr_reader :loader_thread, :queue
64
+ end
65
+
66
+ def autoload(*args) #TODO sync const_defined? ?
67
+ common_auto :load, args
68
+ end
69
+
70
+ def autoload_relative(*args) #TODO sync const_defined? ?
71
+ common_auto :load, args, File.dirname(caller(1, 1)[0][/^(.+):\d+:in `.+'$/, 1])
72
+ end
73
+
74
+ def autorequire(*args) #TODO sync const_defined? ?
75
+ common_auto :require, args
76
+ end
77
+
78
+ def autorequire_relative(*args) #TODO sync const_defined? ?
79
+ common_auto :require, args, File.dirname(caller(1, 1)[0][/^(.+):\d+:in `.+'$/, 1])
80
+ end
81
+
82
+ #def const_defined?(*args)
83
+ # Requirium.synchronize { super }
84
+ #end
85
+
86
+ def const_missing(sym)
87
+ if Thread.current == Requirium.loader_thread
88
+ internal_load(sym)
89
+ else
90
+ cond = CondVar.new
91
+ Requirium.queue.push [self, sym, cond]
92
+ cond.wait_ready
93
+ end
94
+ const_defined?(sym) ? const_get(sym) : super
95
+ end
96
+
97
+ private
98
+
99
+ def common_auto(method, args, dirname = nil)
100
+ if args.length == 1 && args.first.is_a?(Hash)
101
+ args.each { |sym, paths| add_load_item method, sym, paths, dirname }
102
+ return
103
+ end
104
+
105
+ sym, paths = args
106
+ add_load_item method, sym, paths, dirname
107
+ end
108
+
109
+ def add_load_item(method, sym, paths, dirname = nil)
110
+ return if const_defined?(sym)
111
+ paths = [*paths]
112
+ #puts "auto#{method}#{dirname ? '_relative' : ''} #{sym.inspect}, #{paths.map(&:inspect).join(', ')}"
113
+ load_list { |l| l[sym.to_s] = [method, paths, dirname] }
114
+ nil
115
+ end
116
+
117
+ def internal_load(sym)
118
+ return if const_defined?(sym)
119
+ method, paths, dirname = load_list { |l| l[sym.to_s] }
120
+ return unless method
121
+ paths = [sym.to_s.snakecase] if paths.empty?
122
+ paths = paths.map { |path| (Pathname(dirname) + path).to_s } if dirname
123
+ paths.each do |filename|
124
+ #puts "#{method} #{sym.inspect}, #{filename.inspect}"
125
+ raise NoMethodError, "invalid method type: #{method.inspect}" unless [:load, :require].include?(method)
126
+ send(method, filename)
127
+ end
128
+ load_list { |l| l.delete(sym.to_s) } if const_defined?(sym)
129
+ nil
130
+ end
131
+
132
+ def load_list
133
+ (@mutex ||= Mutex.new).synchronize { yield(@load_list ||= {}) }
134
+ end
135
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: requirium
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - SilverPhoenix99
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: facets
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.9'
27
+ description: An autoload alternative
28
+ email:
29
+ - silver.phoenix99@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - README.md
35
+ - lib/requirium.rb
36
+ homepage: https://github.com/SilverPhoenix99/requirium
37
+ licenses:
38
+ - MIT
39
+ metadata: {}
40
+ post_install_message: |
41
+ +----------------------------------------------------------------------------+
42
+ Thank you for choosing Requirium.
43
+
44
+ ==========================================================================
45
+ If you find any bugs, please report them on
46
+ https://github.com/SilverPhoenix99/requirium/issues
47
+
48
+ +----------------------------------------------------------------------------+
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 2.2.2
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: An autoload alternative
68
+ test_files: []
69
+ has_rdoc: