autorequire 0.0.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.
- data/README +337 -0
- data/README.tmpl +73 -0
- data/autorequire-0.0.0.gem +0 -0
- data/emsg.rb +5 -0
- data/gemspec.rb +23 -0
- data/gen_readme.rb +32 -0
- data/install.rb +201 -0
- data/lib/autorequire.rb +152 -0
- data/libgen.rb +12 -0
- data/sample/a.rb +8 -0
- data/sample/b.rb +9 -0
- data/sample/c.rb +16 -0
- data/sample/d.rb +14 -0
- data/sample/e.rb +12 -0
- data/sample/f.rb +18 -0
- data/sample/g.rb +26 -0
- data/sample/h.rb +15 -0
- data/sample/i.rb +9 -0
- data/sample/j.rb +7 -0
- metadata +59 -0
data/README
ADDED
@@ -0,0 +1,337 @@
|
|
1
|
+
URLS
|
2
|
+
|
3
|
+
http://codeforpeople.com/lib/ruby/autorequire/
|
4
|
+
http://rubyforge.org/frs/?group_id=1024
|
5
|
+
|
6
|
+
ABOUT
|
7
|
+
|
8
|
+
autorequire is sleeker, more aerodynamic, greasier version of autoload.
|
9
|
+
|
10
|
+
like autoload it's primary usage is to speed up the load time of large
|
11
|
+
libraries which, themselves, do many requires.
|
12
|
+
|
13
|
+
INSTALL
|
14
|
+
|
15
|
+
gem install autorequire
|
16
|
+
|
17
|
+
VERSION
|
18
|
+
|
19
|
+
0.0.0
|
20
|
+
|
21
|
+
HISTORY
|
22
|
+
|
23
|
+
0.0.0 :
|
24
|
+
|
25
|
+
initial release
|
26
|
+
|
27
|
+
AUTHOR
|
28
|
+
|
29
|
+
ara [dot] t [dot] howard [at] noaa [dot] gov
|
30
|
+
|
31
|
+
SAMPLES
|
32
|
+
|
33
|
+
<========< emsg.rb >========>
|
34
|
+
|
35
|
+
~ > cat emsg.rb
|
36
|
+
#
|
37
|
+
# rescues err and prints msg - support method for samples/*
|
38
|
+
#
|
39
|
+
def emsg
|
40
|
+
yield
|
41
|
+
rescue Exception => e
|
42
|
+
puts "#{ e } (#{ e.class })!"
|
43
|
+
end
|
44
|
+
|
45
|
+
<========< libgen.rb >========>
|
46
|
+
|
47
|
+
~ > cat libgen.rb
|
48
|
+
#
|
49
|
+
# generates a temporaray ruby lib - support method for samples/*
|
50
|
+
#
|
51
|
+
require 'fileutils'
|
52
|
+
def libgen path, libdir = './.lib/'
|
53
|
+
f, fu = File, FileUtils
|
54
|
+
dirname, basename = f.split path
|
55
|
+
dirname = f.join libdir, dirname
|
56
|
+
fu.mkdir_p dirname
|
57
|
+
path = f.join dirname, basename
|
58
|
+
open(path,'w'){|fd| fd << yield}
|
59
|
+
at_exit{ Dir.glob(f.join(libdir, '*')){|e| fu.rm_rf e} }
|
60
|
+
path
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
<========< sample/a.rb >========>
|
65
|
+
|
66
|
+
~ > cat sample/a.rb
|
67
|
+
|
68
|
+
#
|
69
|
+
# simple use is much like autoload
|
70
|
+
#
|
71
|
+
emsg{ p Queue }
|
72
|
+
|
73
|
+
autorequire 'Queue', 'thread'
|
74
|
+
|
75
|
+
emsg{ p Queue }
|
76
|
+
|
77
|
+
~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/a.rb
|
78
|
+
|
79
|
+
Queue (NameError)!
|
80
|
+
Queue
|
81
|
+
|
82
|
+
|
83
|
+
<========< sample/b.rb >========>
|
84
|
+
|
85
|
+
~ > cat sample/b.rb
|
86
|
+
|
87
|
+
#
|
88
|
+
# but we can also specify nested classes. note the alternative hash syntax.
|
89
|
+
# a list of const => lib pairs may also be given.
|
90
|
+
#
|
91
|
+
emsg{ p CGI::Session }
|
92
|
+
|
93
|
+
autorequire 'CGI::Session' => 'cgi/session'
|
94
|
+
|
95
|
+
emsg{ p CGI::Session }
|
96
|
+
|
97
|
+
~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/b.rb
|
98
|
+
|
99
|
+
CGI (NameError)!
|
100
|
+
CGI::Session
|
101
|
+
|
102
|
+
|
103
|
+
<========< sample/c.rb >========>
|
104
|
+
|
105
|
+
~ > cat sample/c.rb
|
106
|
+
|
107
|
+
#
|
108
|
+
# like autoload, calling autorequire on a class defines the lib to be loaded
|
109
|
+
# when the const_missing hook for __that__ class is called
|
110
|
+
#
|
111
|
+
class C
|
112
|
+
lib = libgen('a.rb'){ 'class C::A; end' }
|
113
|
+
|
114
|
+
emsg{ p A }
|
115
|
+
|
116
|
+
autorequire 'A' => lib
|
117
|
+
|
118
|
+
emsg{ p A }
|
119
|
+
end
|
120
|
+
|
121
|
+
emsg{ p A}
|
122
|
+
emsg{ p C::A}
|
123
|
+
|
124
|
+
~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/c.rb
|
125
|
+
|
126
|
+
A (NameError)!
|
127
|
+
C::A
|
128
|
+
A (NameError)!
|
129
|
+
C::A
|
130
|
+
|
131
|
+
|
132
|
+
<========< sample/d.rb >========>
|
133
|
+
|
134
|
+
~ > cat sample/d.rb
|
135
|
+
|
136
|
+
#
|
137
|
+
# however, we can scope the constant to the top-level, even from within
|
138
|
+
# another class
|
139
|
+
#
|
140
|
+
emsg{ p A }
|
141
|
+
|
142
|
+
class C
|
143
|
+
lib = libgen('a.rb'){ 'class ::A; end' }
|
144
|
+
autorequire '::A' => lib
|
145
|
+
emsg{ p A }
|
146
|
+
emsg{ p ::A }
|
147
|
+
end
|
148
|
+
|
149
|
+
emsg{ p A }
|
150
|
+
|
151
|
+
~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/d.rb
|
152
|
+
|
153
|
+
A (NameError)!
|
154
|
+
A (NameError)!
|
155
|
+
A
|
156
|
+
A
|
157
|
+
|
158
|
+
|
159
|
+
<========< sample/e.rb >========>
|
160
|
+
|
161
|
+
~ > cat sample/e.rb
|
162
|
+
|
163
|
+
#
|
164
|
+
# this is a nice way to setup bulk autoloads in a large library
|
165
|
+
#
|
166
|
+
emsg{ p Net::Ftp }
|
167
|
+
emsg{ p CGI::Session }
|
168
|
+
|
169
|
+
module M
|
170
|
+
autorequire '::Net::FTP' => 'net/ftp', '::CGI::Session' => 'cgi/session'
|
171
|
+
end
|
172
|
+
|
173
|
+
emsg{ p Net::FTP }
|
174
|
+
emsg{ p CGI::Session }
|
175
|
+
|
176
|
+
~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/e.rb
|
177
|
+
|
178
|
+
Net (NameError)!
|
179
|
+
CGI (NameError)!
|
180
|
+
Net::FTP
|
181
|
+
CGI::Session
|
182
|
+
|
183
|
+
|
184
|
+
<========< sample/f.rb >========>
|
185
|
+
|
186
|
+
~ > cat sample/f.rb
|
187
|
+
|
188
|
+
#
|
189
|
+
# you may have notice autorequire works for nested constants. it does this be
|
190
|
+
# dynamically setting up proxy modules to resolve a name. once the names have
|
191
|
+
# actually been resolved the proxy is dropped.
|
192
|
+
#
|
193
|
+
emsg{ p Net }
|
194
|
+
emsg{ p CGI }
|
195
|
+
|
196
|
+
autorequire '::Net::FTP' => 'net/ftp', '::CGI::Session' => 'cgi/session'
|
197
|
+
|
198
|
+
emsg{ p Net }
|
199
|
+
emsg{ p CGI }
|
200
|
+
|
201
|
+
emsg{ p Net::FTP }
|
202
|
+
emsg{ p CGI::Session }
|
203
|
+
|
204
|
+
emsg{ p Net }
|
205
|
+
emsg{ p CGI }
|
206
|
+
|
207
|
+
~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/f.rb
|
208
|
+
|
209
|
+
Net (NameError)!
|
210
|
+
CGI (NameError)!
|
211
|
+
"ConstProxy(Net)"
|
212
|
+
"ConstProxy(CGI)"
|
213
|
+
Net::FTP
|
214
|
+
CGI::Session
|
215
|
+
Net
|
216
|
+
CGI
|
217
|
+
|
218
|
+
|
219
|
+
<========< sample/g.rb >========>
|
220
|
+
|
221
|
+
~ > cat sample/g.rb
|
222
|
+
|
223
|
+
#
|
224
|
+
# this actually works for arbitrarily deep const nestings
|
225
|
+
#
|
226
|
+
lib =
|
227
|
+
libgen('a/b/c/d.rb'){
|
228
|
+
'
|
229
|
+
module A
|
230
|
+
module B
|
231
|
+
module C
|
232
|
+
class D
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
'
|
238
|
+
}
|
239
|
+
|
240
|
+
autorequire 'A::B::C::D' => lib
|
241
|
+
|
242
|
+
p A
|
243
|
+
p A::B
|
244
|
+
p A::B::C
|
245
|
+
p A::B::C::D
|
246
|
+
p A::B::C
|
247
|
+
p A::B
|
248
|
+
p A
|
249
|
+
|
250
|
+
~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/g.rb
|
251
|
+
|
252
|
+
"ConstProxy(A)"
|
253
|
+
"ConstProxy(B)"
|
254
|
+
"ConstProxy(C)"
|
255
|
+
A::B::C::D
|
256
|
+
A::B::C
|
257
|
+
A::B
|
258
|
+
A
|
259
|
+
|
260
|
+
|
261
|
+
<========< sample/h.rb >========>
|
262
|
+
|
263
|
+
~ > cat sample/h.rb
|
264
|
+
|
265
|
+
#
|
266
|
+
# if you don't specify which lib to load it's name is guessed using a rather
|
267
|
+
# naive approach.
|
268
|
+
#
|
269
|
+
emsg{ p PStore }
|
270
|
+
emsg{ p CGI::Session }
|
271
|
+
emsg{ p FileUtils }
|
272
|
+
|
273
|
+
autorequire 'PStore' # requires 'pstore'
|
274
|
+
autorequire 'CGI::Session' # requires 'cgi/session'
|
275
|
+
autorequire '::FileUtils' # requires 'fileutils'
|
276
|
+
|
277
|
+
emsg{ p PStore }
|
278
|
+
emsg{ p CGI::Session }
|
279
|
+
emsg{ p FileUtils }
|
280
|
+
|
281
|
+
~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/h.rb
|
282
|
+
|
283
|
+
PStore (NameError)!
|
284
|
+
CGI (NameError)!
|
285
|
+
FileUtils
|
286
|
+
PStore
|
287
|
+
CGI::Session
|
288
|
+
FileUtils
|
289
|
+
|
290
|
+
|
291
|
+
<========< sample/i.rb >========>
|
292
|
+
|
293
|
+
~ > cat sample/i.rb
|
294
|
+
|
295
|
+
#
|
296
|
+
# if you're feeling risque you can set Autorequire.everything = true to use
|
297
|
+
# this default loading for __any__ const missing.
|
298
|
+
#
|
299
|
+
Autorequire.everything = 42
|
300
|
+
|
301
|
+
emsg{ p PStore }
|
302
|
+
emsg{ p CGI::Session }
|
303
|
+
emsg{ p FileUtils }
|
304
|
+
|
305
|
+
~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/i.rb
|
306
|
+
|
307
|
+
PStore
|
308
|
+
CGI::Session
|
309
|
+
FileUtils
|
310
|
+
|
311
|
+
|
312
|
+
<========< sample/j.rb >========>
|
313
|
+
|
314
|
+
~ > cat sample/j.rb
|
315
|
+
|
316
|
+
#
|
317
|
+
# you do, at least, get a meaningful error if the const to lib translation
|
318
|
+
# fails
|
319
|
+
#
|
320
|
+
autorequire 'FuBar' => 'does-not-exist.rb'
|
321
|
+
|
322
|
+
emsg{ p FuBar }
|
323
|
+
|
324
|
+
~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/j.rb
|
325
|
+
|
326
|
+
resolving <FuBar> by loading <does-not-exist.rb> failed (Autorequire::NameError)!
|
327
|
+
|
328
|
+
|
329
|
+
CAVEATS
|
330
|
+
|
331
|
+
this library is experimental. nonetheless it's relatively straight forward
|
332
|
+
and i have no plans to change it's interface - though i may add to it in
|
333
|
+
future release.
|
334
|
+
|
335
|
+
LICENSE
|
336
|
+
|
337
|
+
same as ruby's
|
data/README.tmpl
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
URLS
|
2
|
+
|
3
|
+
http://codeforpeople.com/lib/ruby/autorequire/
|
4
|
+
http://rubyforge.org/frs/?group_id=1024
|
5
|
+
|
6
|
+
ABOUT
|
7
|
+
|
8
|
+
autorequire is sleeker, more aerodynamic, greasier version of autoload.
|
9
|
+
|
10
|
+
like autoload it's primary usage is to speed up the load time of large
|
11
|
+
libraries which, themselves, do many requires.
|
12
|
+
|
13
|
+
INSTALL
|
14
|
+
|
15
|
+
gem install autorequire
|
16
|
+
|
17
|
+
VERSION
|
18
|
+
|
19
|
+
0.0.0
|
20
|
+
|
21
|
+
HISTORY
|
22
|
+
|
23
|
+
0.0.0 :
|
24
|
+
|
25
|
+
initial release
|
26
|
+
|
27
|
+
AUTHOR
|
28
|
+
|
29
|
+
ara [dot] t [dot] howard [at] noaa [dot] gov
|
30
|
+
|
31
|
+
SAMPLES
|
32
|
+
|
33
|
+
<========< emsg.rb >========>
|
34
|
+
|
35
|
+
~ > cat emsg.rb
|
36
|
+
#
|
37
|
+
# rescues err and prints msg - support method for samples/*
|
38
|
+
#
|
39
|
+
def emsg
|
40
|
+
yield
|
41
|
+
rescue Exception => e
|
42
|
+
puts "#{ e } (#{ e.class })!"
|
43
|
+
end
|
44
|
+
|
45
|
+
<========< libgen.rb >========>
|
46
|
+
|
47
|
+
~ > cat libgen.rb
|
48
|
+
#
|
49
|
+
# generates a temporaray ruby lib - support method for samples/*
|
50
|
+
#
|
51
|
+
require 'fileutils'
|
52
|
+
def libgen path, libdir = './.lib/'
|
53
|
+
f, fu = File, FileUtils
|
54
|
+
dirname, basename = f.split path
|
55
|
+
dirname = f.join libdir, dirname
|
56
|
+
fu.mkdir_p dirname
|
57
|
+
path = f.join dirname, basename
|
58
|
+
open(path,'w'){|fd| fd << yield}
|
59
|
+
at_exit{ Dir.glob(f.join(libdir, '*')){|e| fu.rm_rf e} }
|
60
|
+
path
|
61
|
+
end
|
62
|
+
|
63
|
+
@samples
|
64
|
+
|
65
|
+
CAVEATS
|
66
|
+
|
67
|
+
this library is experimental. nonetheless it's relatively straight forward
|
68
|
+
and i have no plans to change it's interface - though i may add to it in
|
69
|
+
future release.
|
70
|
+
|
71
|
+
LICENSE
|
72
|
+
|
73
|
+
same as ruby's
|
File without changes
|
data/emsg.rb
ADDED
data/gemspec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
Gem::Specification::new do |spec|
|
6
|
+
spec.name = lib
|
7
|
+
spec.version = version
|
8
|
+
spec.platform = Gem::Platform::RUBY
|
9
|
+
spec.summary = lib
|
10
|
+
|
11
|
+
# spec.files = Dir[ File::join("{lib,bin}", "*") ]
|
12
|
+
# spec.require_path = "lib"
|
13
|
+
|
14
|
+
spec.files = Dir::glob "**/**"
|
15
|
+
spec.executables = Dir::glob("bin/*").map{|exe| File::basename exe}
|
16
|
+
|
17
|
+
spec.has_rdoc = File::exist? "doc"
|
18
|
+
spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
|
19
|
+
|
20
|
+
spec.author = "Ara T. Howard"
|
21
|
+
spec.email = "ara.t.howard@noaa.gov"
|
22
|
+
spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
|
23
|
+
end
|
data/gen_readme.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
$VERBOSE=nil
|
2
|
+
def indent s, n = 2
|
3
|
+
ws = ' ' * n
|
4
|
+
s.gsub %r/^/, ws
|
5
|
+
end
|
6
|
+
|
7
|
+
template = IO::read 'README.tmpl'
|
8
|
+
|
9
|
+
samples = ''
|
10
|
+
prompt = '~ > '
|
11
|
+
|
12
|
+
libs = Dir['lib/*'].map{|lib| " -r #{ lib } "}.join
|
13
|
+
|
14
|
+
Dir['sample/*'].sort.each do |sample|
|
15
|
+
samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
|
16
|
+
|
17
|
+
cmd = "cat #{ sample }"
|
18
|
+
samples << indent(prompt + cmd, 2) << "\n\n"
|
19
|
+
samples << indent(`#{ cmd }`, 4) << "\n"
|
20
|
+
|
21
|
+
cmd = "ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb #{ sample }"
|
22
|
+
samples << indent(prompt + cmd, 2) << "\n\n"
|
23
|
+
|
24
|
+
#cmd = "ruby -r ./emsg.rb -I ./lib #{ libs } #{ sample }"
|
25
|
+
cmd = "ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb #{ sample }"
|
26
|
+
samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
|
27
|
+
end
|
28
|
+
|
29
|
+
#samples.gsub! %r/^/, ' '
|
30
|
+
|
31
|
+
readme = template.gsub %r/^[\ ]*@samples\s*$/, samples
|
32
|
+
print readme
|
data/install.rb
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'find'
|
4
|
+
require 'ftools'
|
5
|
+
require 'tempfile'
|
6
|
+
include Config
|
7
|
+
|
8
|
+
LIBDIR = "lib"
|
9
|
+
LIBDIR_MODE = 0644
|
10
|
+
|
11
|
+
BINDIR = "bin"
|
12
|
+
BINDIR_MODE = 0755
|
13
|
+
|
14
|
+
|
15
|
+
$srcdir = CONFIG["srcdir"]
|
16
|
+
$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
17
|
+
$libdir = File.join(CONFIG["libdir"], "ruby", $version)
|
18
|
+
$archdir = File.join($libdir, CONFIG["arch"])
|
19
|
+
$site_libdir = $:.find {|x| x =~ /site_ruby$/}
|
20
|
+
$bindir = CONFIG["bindir"] || CONFIG['BINDIR']
|
21
|
+
$ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
|
22
|
+
$ruby_ext = CONFIG['EXEEXT'] || ''
|
23
|
+
$ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
|
24
|
+
|
25
|
+
if !$site_libdir
|
26
|
+
$site_libdir = File.join($libdir, "site_ruby")
|
27
|
+
elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
|
28
|
+
$site_libdir = File.join($site_libdir, $version)
|
29
|
+
end
|
30
|
+
|
31
|
+
def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
|
32
|
+
#{{{
|
33
|
+
path = []
|
34
|
+
dir = []
|
35
|
+
Find.find(srcdir) do |f|
|
36
|
+
next unless FileTest.file?(f)
|
37
|
+
next if (f = f[srcdir.length+1..-1]) == nil
|
38
|
+
next if (/CVS$/ =~ File.dirname(f))
|
39
|
+
next if f =~ %r/\.lnk/
|
40
|
+
path.push f
|
41
|
+
dir |= [File.dirname(f)]
|
42
|
+
end
|
43
|
+
for f in dir
|
44
|
+
next if f == "."
|
45
|
+
next if f == "CVS"
|
46
|
+
File::makedirs(File.join(destdir, f))
|
47
|
+
end
|
48
|
+
for f in path
|
49
|
+
next if (/\~$/ =~ f)
|
50
|
+
next if (/^\./ =~ File.basename(f))
|
51
|
+
unless bin
|
52
|
+
File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
|
53
|
+
else
|
54
|
+
from = File.join(srcdir, f)
|
55
|
+
to = File.join(destdir, f)
|
56
|
+
shebangify(from) do |sf|
|
57
|
+
$deferr.print from, " -> ", File::catname(from, to), "\n"
|
58
|
+
$deferr.printf "chmod %04o %s\n", mode, to
|
59
|
+
File::install(sf, to, mode, false)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
#}}}
|
64
|
+
end
|
65
|
+
def shebangify f
|
66
|
+
#{{{
|
67
|
+
open(f) do |fd|
|
68
|
+
buf = fd.read 42
|
69
|
+
if buf =~ %r/^\s*#\s*!.*ruby/o
|
70
|
+
ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
|
71
|
+
begin
|
72
|
+
fd.rewind
|
73
|
+
ftmp.puts "#!#{ $ruby }"
|
74
|
+
while((buf = fd.read(8192)))
|
75
|
+
ftmp.write buf
|
76
|
+
end
|
77
|
+
ftmp.close
|
78
|
+
yield ftmp.path
|
79
|
+
ensure
|
80
|
+
ftmp.close!
|
81
|
+
end
|
82
|
+
else
|
83
|
+
yield f
|
84
|
+
end
|
85
|
+
end
|
86
|
+
#}}}
|
87
|
+
end
|
88
|
+
def ARGV.switch
|
89
|
+
#{{{
|
90
|
+
return nil if self.empty?
|
91
|
+
arg = self.shift
|
92
|
+
return nil if arg == '--'
|
93
|
+
if arg =~ /^-(.)(.*)/
|
94
|
+
return arg if $1 == '-'
|
95
|
+
raise 'unknown switch "-"' if $2.index('-')
|
96
|
+
self.unshift "-#{$2}" if $2.size > 0
|
97
|
+
"-#{$1}"
|
98
|
+
else
|
99
|
+
self.unshift arg
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
#}}}
|
103
|
+
end
|
104
|
+
def ARGV.req_arg
|
105
|
+
#{{{
|
106
|
+
self.shift || raise('missing argument')
|
107
|
+
#}}}
|
108
|
+
end
|
109
|
+
def linkify d, linked = []
|
110
|
+
#--{{{
|
111
|
+
if test ?d, d
|
112
|
+
versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
|
113
|
+
versioned.each do |v|
|
114
|
+
src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
|
115
|
+
lnk = nil
|
116
|
+
begin
|
117
|
+
if test ?l, dst
|
118
|
+
lnk = "#{ dst }.lnk"
|
119
|
+
puts "#{ dst } -> #{ lnk }"
|
120
|
+
File::rename dst, lnk
|
121
|
+
end
|
122
|
+
unless test ?e, dst
|
123
|
+
puts "#{ src } -> #{ dst }"
|
124
|
+
File::copy src, dst
|
125
|
+
linked << dst
|
126
|
+
end
|
127
|
+
ensure
|
128
|
+
if lnk
|
129
|
+
at_exit do
|
130
|
+
puts "#{ lnk } -> #{ dst }"
|
131
|
+
File::rename lnk, dst
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
linked
|
138
|
+
#--}}}
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
#
|
143
|
+
# main program
|
144
|
+
#
|
145
|
+
|
146
|
+
libdir = $site_libdir
|
147
|
+
bindir = $bindir
|
148
|
+
no_linkify = false
|
149
|
+
linked = nil
|
150
|
+
help = false
|
151
|
+
|
152
|
+
usage = <<-usage
|
153
|
+
#{ File::basename $0 }
|
154
|
+
-d, --destdir <destdir>
|
155
|
+
-l, --libdir <libdir>
|
156
|
+
-b, --bindir <bindir>
|
157
|
+
-r, --ruby <ruby>
|
158
|
+
-n, --no_linkify
|
159
|
+
-h, --help
|
160
|
+
usage
|
161
|
+
|
162
|
+
begin
|
163
|
+
while switch = ARGV.switch
|
164
|
+
case switch
|
165
|
+
when '-d', '--destdir'
|
166
|
+
libdir = ARGV.req_arg
|
167
|
+
when '-l', '--libdir'
|
168
|
+
libdir = ARGV.req_arg
|
169
|
+
when '-b', '--bindir'
|
170
|
+
bindir = ARGV.req_arg
|
171
|
+
when '-r', '--ruby'
|
172
|
+
$ruby = ARGV.req_arg
|
173
|
+
when '-n', '--no_linkify'
|
174
|
+
no_linkify = true
|
175
|
+
when '-h', '--help'
|
176
|
+
help = true
|
177
|
+
else
|
178
|
+
raise "unknown switch #{switch.dump}"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
rescue
|
182
|
+
STDERR.puts $!.to_s
|
183
|
+
STDERR.puts usage
|
184
|
+
exit 1
|
185
|
+
end
|
186
|
+
|
187
|
+
if help
|
188
|
+
STDOUT.puts usage
|
189
|
+
exit
|
190
|
+
end
|
191
|
+
|
192
|
+
unless no_linkify
|
193
|
+
linked = linkify('lib') + linkify('bin')
|
194
|
+
end
|
195
|
+
|
196
|
+
install_rb(LIBDIR, libdir, LIBDIR_MODE)
|
197
|
+
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
|
198
|
+
|
199
|
+
if linked
|
200
|
+
linked.each{|path| File::rm_f path}
|
201
|
+
end
|
data/lib/autorequire.rb
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
module Autorequire
|
2
|
+
class NameError < ::NameError; end
|
3
|
+
class LoadError < ::LoadError; end
|
4
|
+
class << self
|
5
|
+
attr_accessor "everything"
|
6
|
+
alias_method "everything?", "everything"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Module
|
11
|
+
alias_method "const_missing!", "const_missing"
|
12
|
+
def const_missing c
|
13
|
+
c = c.to_s
|
14
|
+
|
15
|
+
if autorequire.has_key? c
|
16
|
+
value = autorequire[c]
|
17
|
+
if ConstProxy?(value)
|
18
|
+
return value
|
19
|
+
else
|
20
|
+
value.flatten.each do |lib|
|
21
|
+
begin
|
22
|
+
require lib
|
23
|
+
rescue LoadError
|
24
|
+
#raise NameError, "resolving <#{ c }> by loading <#{ lib }> failed"
|
25
|
+
raise Autorequire::NameError, "resolving <#{ c }> by loading <#{ lib }> failed"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
elsif Autorequire.everything?
|
30
|
+
lib4 = lambda{|k| k.to_s.sub(%r/^::/,'').downcase.gsub(%r/::/, File::SEPARATOR)}
|
31
|
+
lib = Object == self ? lib4[c] : lib4["#{ name }::#{ c }"]
|
32
|
+
begin
|
33
|
+
require lib
|
34
|
+
rescue LoadError
|
35
|
+
raise Autorequire::NameError, "resolving <#{ c }> by loading <#{ lib }> failed"
|
36
|
+
end
|
37
|
+
else
|
38
|
+
#const_missing! c
|
39
|
+
raise NameError, c
|
40
|
+
end
|
41
|
+
|
42
|
+
#begin
|
43
|
+
if ConstProxy?(self)
|
44
|
+
raise NameError, c unless to_const.const_defined? c
|
45
|
+
to_const.const_get c
|
46
|
+
else
|
47
|
+
raise NameError, c unless const_defined? c
|
48
|
+
const_get c
|
49
|
+
end
|
50
|
+
#rescue NameError => ne
|
51
|
+
##const_missing! c
|
52
|
+
#raise NameError, c
|
53
|
+
#end
|
54
|
+
end
|
55
|
+
def autorequire c = nil, *libs
|
56
|
+
if c
|
57
|
+
lib4 = lambda{|k| k.to_s.sub(%r/^::/,'').downcase.gsub(%r/::/, File::SEPARATOR)}
|
58
|
+
h = Hash === c ? c : {c => libs}
|
59
|
+
h.each do |c,libs|
|
60
|
+
libs << lib4[c] if libs.empty?
|
61
|
+
m = self
|
62
|
+
if c =~ %r/::/
|
63
|
+
if c =~ %r/^::/
|
64
|
+
c = c.gsub %r/^::/, ''
|
65
|
+
::Object.autorequire(c, *libs)
|
66
|
+
next
|
67
|
+
end
|
68
|
+
list = c.split %r/::/
|
69
|
+
c = list.pop
|
70
|
+
while((name = list.shift))
|
71
|
+
cp = ConstProxy(name,m)
|
72
|
+
m.autorequire[name] = cp
|
73
|
+
m = cp
|
74
|
+
end
|
75
|
+
end
|
76
|
+
m.autorequire[c.to_s] = [libs].flatten
|
77
|
+
end
|
78
|
+
self
|
79
|
+
else
|
80
|
+
@autorequire ||= {}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
def Autorequire(*a, &b) autorequire(*a, &b) end
|
84
|
+
end
|
85
|
+
|
86
|
+
module ConstProxy
|
87
|
+
def self.new name, parent
|
88
|
+
name = name.to_s
|
89
|
+
Module.new do
|
90
|
+
include ConstProxy
|
91
|
+
singleton_class = class << self; self; end
|
92
|
+
singleton_class.module_eval do
|
93
|
+
define_method('name'){ name }
|
94
|
+
define_method('parent'){ parent }
|
95
|
+
define_method('to_s'){ "ConstProxy(#{ name })" }
|
96
|
+
define_method('inspect'){ "\"#{ to_s }\"" }
|
97
|
+
define_method('to_const'){
|
98
|
+
if ConstProxy?(parent)
|
99
|
+
parent.to_const.const_get name # recurse
|
100
|
+
else
|
101
|
+
parent.const_get name
|
102
|
+
end
|
103
|
+
}
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
module ::Kernel
|
108
|
+
def ConstProxy(*a, &b) ConstProxy.new(*a, &b) end
|
109
|
+
def ConstProxy?(other) other.is_a?(Module) and other.ancestors.include?(ConstProxy) end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class Object
|
114
|
+
def autorequire(*a, &b) self.class.autorequire(*a, &b) end
|
115
|
+
def Autorequire(*a, &b) self.class.autorequire(*a, &b) end
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
if $0 == __FILE__
|
121
|
+
autorequire 'Net::FTP' => %w( net/ftp net/http )
|
122
|
+
p Net
|
123
|
+
p Net::FTP
|
124
|
+
p Net
|
125
|
+
|
126
|
+
|
127
|
+
autorequire 'A::B::C::D' => 'a/b/c/d'
|
128
|
+
p A
|
129
|
+
p A::B
|
130
|
+
p A::B::C
|
131
|
+
p A::B::C::D
|
132
|
+
p A::B::C
|
133
|
+
p A::B
|
134
|
+
p A
|
135
|
+
|
136
|
+
autorequire 'Net::FTP'
|
137
|
+
p Net
|
138
|
+
p Net::FTP
|
139
|
+
p Net
|
140
|
+
|
141
|
+
autorequire 'CGI::Session'
|
142
|
+
p CGI
|
143
|
+
p CGI::Session
|
144
|
+
p CGI
|
145
|
+
|
146
|
+
autorequire 'PStore'
|
147
|
+
p PStore
|
148
|
+
|
149
|
+
Autorequire.everything = true
|
150
|
+
p CGI::Session
|
151
|
+
p CGI
|
152
|
+
end
|
data/libgen.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
def libgen path, libdir = './.lib/'
|
4
|
+
f, fu = File, FileUtils
|
5
|
+
dirname, basename = f.split path
|
6
|
+
dirname = f.join libdir, dirname
|
7
|
+
fu.mkdir_p dirname
|
8
|
+
path = f.join dirname, basename
|
9
|
+
open(path,'w'){|fd| fd << yield}
|
10
|
+
at_exit{ Dir.glob(f.join(libdir, '*')){|e| fu.rm_rf e} }
|
11
|
+
path
|
12
|
+
end
|
data/sample/a.rb
ADDED
data/sample/b.rb
ADDED
data/sample/c.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#
|
2
|
+
# like autoload, calling autorequire on a class defines the lib to be loaded
|
3
|
+
# when the const_missing hook for __that__ class is called
|
4
|
+
#
|
5
|
+
class C
|
6
|
+
lib = libgen('a.rb'){ 'class C::A; end' }
|
7
|
+
|
8
|
+
emsg{ p A }
|
9
|
+
|
10
|
+
autorequire 'A' => lib
|
11
|
+
|
12
|
+
emsg{ p A }
|
13
|
+
end
|
14
|
+
|
15
|
+
emsg{ p A}
|
16
|
+
emsg{ p C::A}
|
data/sample/d.rb
ADDED
data/sample/e.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#
|
2
|
+
# this is a nice way to setup bulk autoloads in a large library
|
3
|
+
#
|
4
|
+
emsg{ p Net::Ftp }
|
5
|
+
emsg{ p CGI::Session }
|
6
|
+
|
7
|
+
module M
|
8
|
+
autorequire '::Net::FTP' => 'net/ftp', '::CGI::Session' => 'cgi/session'
|
9
|
+
end
|
10
|
+
|
11
|
+
emsg{ p Net::FTP }
|
12
|
+
emsg{ p CGI::Session }
|
data/sample/f.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#
|
2
|
+
# you may have notice autorequire works for nested constants. it does this be
|
3
|
+
# dynamically setting up proxy modules to resolve a name. once the names have
|
4
|
+
# actually been resolved the proxy is dropped.
|
5
|
+
#
|
6
|
+
emsg{ p Net }
|
7
|
+
emsg{ p CGI }
|
8
|
+
|
9
|
+
autorequire '::Net::FTP' => 'net/ftp', '::CGI::Session' => 'cgi/session'
|
10
|
+
|
11
|
+
emsg{ p Net }
|
12
|
+
emsg{ p CGI }
|
13
|
+
|
14
|
+
emsg{ p Net::FTP }
|
15
|
+
emsg{ p CGI::Session }
|
16
|
+
|
17
|
+
emsg{ p Net }
|
18
|
+
emsg{ p CGI }
|
data/sample/g.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#
|
2
|
+
# this actually works for arbitrarily deep const nestings
|
3
|
+
#
|
4
|
+
lib =
|
5
|
+
libgen('a/b/c/d.rb'){
|
6
|
+
'
|
7
|
+
module A
|
8
|
+
module B
|
9
|
+
module C
|
10
|
+
class D
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
'
|
16
|
+
}
|
17
|
+
|
18
|
+
autorequire 'A::B::C::D' => lib
|
19
|
+
|
20
|
+
p A
|
21
|
+
p A::B
|
22
|
+
p A::B::C
|
23
|
+
p A::B::C::D
|
24
|
+
p A::B::C
|
25
|
+
p A::B
|
26
|
+
p A
|
data/sample/h.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#
|
2
|
+
# if you don't specify which lib to load it's name is guessed using a rather
|
3
|
+
# naive approach.
|
4
|
+
#
|
5
|
+
emsg{ p PStore }
|
6
|
+
emsg{ p CGI::Session }
|
7
|
+
emsg{ p FileUtils }
|
8
|
+
|
9
|
+
autorequire 'PStore' # requires 'pstore'
|
10
|
+
autorequire 'CGI::Session' # requires 'cgi/session'
|
11
|
+
autorequire '::FileUtils' # requires 'fileutils'
|
12
|
+
|
13
|
+
emsg{ p PStore }
|
14
|
+
emsg{ p CGI::Session }
|
15
|
+
emsg{ p FileUtils }
|
data/sample/i.rb
ADDED
data/sample/j.rb
ADDED
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: autorequire
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.0
|
7
|
+
date: 2006-04-11 00:00:00.000000 -06:00
|
8
|
+
summary: autorequire
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: ara.t.howard@noaa.gov
|
12
|
+
homepage: http://codeforpeople.com/lib/ruby/autorequire/
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
signing_key:
|
28
|
+
cert_chain:
|
29
|
+
authors:
|
30
|
+
- Ara T. Howard
|
31
|
+
files:
|
32
|
+
- lib
|
33
|
+
- install.rb
|
34
|
+
- gemspec.rb
|
35
|
+
- autorequire-0.0.0.gem
|
36
|
+
- README.tmpl
|
37
|
+
- gen_readme.rb
|
38
|
+
- sample
|
39
|
+
- README
|
40
|
+
- emsg.rb
|
41
|
+
- libgen.rb
|
42
|
+
- lib/autorequire.rb
|
43
|
+
- sample/a.rb
|
44
|
+
- sample/f.rb
|
45
|
+
- sample/b.rb
|
46
|
+
- sample/e.rb
|
47
|
+
- sample/c.rb
|
48
|
+
- sample/d.rb
|
49
|
+
- sample/i.rb
|
50
|
+
- sample/j.rb
|
51
|
+
- sample/h.rb
|
52
|
+
- sample/g.rb
|
53
|
+
test_files: []
|
54
|
+
rdoc_options: []
|
55
|
+
extra_rdoc_files: []
|
56
|
+
executables: []
|
57
|
+
extensions: []
|
58
|
+
requirements: []
|
59
|
+
dependencies: []
|