Class: Main::Base
Defined Under Namespace
Modules: DSL
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from DSL
argument, default_options!, environment, keyword, mode, option, parameter
Constructor Details
#initialize(argv = ARGV, env = ENV, opts = {}) ⇒ Base
Returns a new instance of Base.
203
204
205
206
207
208
209
|
# File 'lib/main/base.rb', line 203
def initialize argv = ARGV, env = ENV, opts = {}
@argv, @env, @opts = argv, env, opts
setup_finalizers
setup_io_restoration
setup_io_redirection
setup_logging
end
|
Class Method Details
.context(&block) ⇒ Object
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/main/base.rb', line 106
def context &block
@@context ||= []
unless block
@@context.last
else
begin
@@context.push self
block.call @@context.last
ensure
@@context.pop
end
end
end
|
.create(parent = Base, *a, &b) ⇒ Object
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/main/base.rb', line 95
def create parent = Base, *a, &b
Class.new parent do |child|
child.parent = parent unless parent == Base
parent.children.add child
child.context do
child.class_eval &b if b
child.default_options!
end
end
end
|
.fully_qualified_mode ⇒ Object
120
121
122
123
124
125
126
127
|
# File 'lib/main/base.rb', line 120
def fully_qualified_mode
list = []
ancestors.each do |ancestor|
break unless ancestor < Base
list << ancestor.mode_name
end
list.reverse[1..-1]
end
|
.inheritable_attribute(name, &block) ⇒ Object
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
# File 'lib/main/base.rb', line 52
def self.inheritable_attribute name, &block
block ||= lambda{}
attribute( name ){
catch :value do
if parent?
value = parent.send name
value =
begin
Util.mcp value
rescue
value.clone rescue value.dup
end
throw :value, value
end
instance_eval &block
end
}
end
|
.method_added(m) ⇒ Object
41
42
43
44
45
46
47
48
49
50
|
# File 'lib/main/base.rb', line 41
def method_added m
return if @in_method_added
super if defined? super
@in_method_added = true
begin
wrap_run! if m.to_s == 'run'
ensure
@in_method_added = false
end
end
|
.mode_name=(value) ⇒ Object
77
|
# File 'lib/main/base.rb', line 77
def mode_name=(value) @mode_name = Mode.new value end
|
129
|
# File 'lib/main/base.rb', line 129
def run(&b) define_method(:run, &b) end
|
.wrap_run! ⇒ Object
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
# File 'lib/main/base.rb', line 4
def wrap_run!
const_set :RUN, instance_method(:run)
class_eval do
def run *a, &b
status =
catch :exit do
begin
argv.push "--#{ argv.shift }" if argv.first == 'help'
return mode_run! if mode_given?
parse_parameters
if params['help'] and params['help'].given?
print usage.to_s
exit
end
pre_run
self.class.const_get(:RUN).bind(self).call(*a, &b)
post_run
finalize
rescue Exception => e
handle_exception e
end
nil
end
handle_throw status
end
end
end
|
Instance Method Details
#fcall(obj, m, *argv, &block) ⇒ Object
374
375
376
377
378
379
380
381
382
383
384
|
# File 'lib/main/base.rb', line 374
def fcall obj, m, *argv, &block
m = obj.method m
arity = m.arity
if arity >= 0
argv = argv[0, arity]
else
arity = arity.abs - 1
argv = argv[0, arity] + argv[arity .. -1]
end
m.call *argv, &block
end
|
219
220
221
|
# File 'lib/main/base.rb', line 219
def finalize
while((f = @finalizers.pop)); f.call; end
end
|
#handle_exception(e) ⇒ Object
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
|
# File 'lib/main/base.rb', line 346
def handle_exception e
if e.respond_to?(:error_handler_before)
fcall(e, :error_handler_before, self)
end
if e.respond_to?(:error_handler_instead)
fcall(e, :error_handler_instead, self)
else
if e.respond_to? :status
exit_status(( e.status ))
end
if Softspoken === e or SystemExit === e
stderr.puts e.message unless(SystemExit === e and e.message.to_s == 'exit')
else
fatal{ e }
end
end
if e.respond_to?(:error_handler_after)
fcall(e, :error_handler_after, self)
end
exit_status(( exit_failure )) if exit_status == exit_success
exit_status(( Integer(exit_status) rescue(exit_status ? 0 : 1) ))
exit exit_status
end
|
#handle_throw(status) ⇒ Object
386
387
388
|
# File 'lib/main/base.rb', line 386
def handle_throw status
exit(( Integer(status) rescue 0 ))
end
|
#help!(status = 0) ⇒ Object
341
342
343
344
|
# File 'lib/main/base.rb', line 341
def help! status = 0
print usage.to_s
exit(status)
end
|
#instance_eval_block(*argv, &block) ⇒ Object
398
399
400
401
402
403
404
405
|
# File 'lib/main/base.rb', line 398
def instance_eval_block *argv, &block
sc =
class << self
self
end
sc.module_eval{ define_method '__instance_eval_block', &block }
fcall self, '__instance_eval_block', *argv, &block
end
|
#logger=(log) ⇒ Object
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
# File 'lib/main/base.rb', line 233
def logger= log
unless(defined?(@logger) and @logger == log)
case log
when Logger
@logger = log
when IO, StringIO
@logger = Logger.new log
@logger.level = logger_level
else
@logger = Logger.new *log
@logger.level = logger_level
end
end
@logger
end
|
#mode_given? ⇒ Boolean
320
321
322
323
324
325
326
327
328
|
# File 'lib/main/base.rb', line 320
def mode_given?
begin
modes.size > 0 and
argv.size > 0 and
modes.find_by_mode(argv.first)
rescue Mode::Ambiguous
true
end
end
|
#mode_run! ⇒ Object
329
330
331
332
333
334
335
|
# File 'lib/main/base.rb', line 329
def mode_run!
mode = modes.find_by_mode argv.shift
klass = modes[mode] or abort "bad mode <#{ mode }>"
main = klass.new @argv, @env, @opts
main.mode = mode
main.run
end
|
336
337
338
|
# File 'lib/main/base.rb', line 336
def modes
self.class.modes
end
|
#parse_parameters ⇒ Object
303
304
305
306
307
308
309
310
311
|
# File 'lib/main/base.rb', line 303
def parse_parameters
pre_parse_parameters
self.class.parameters.parse @argv, @env
@params = Parameter::Table.new
self.class.parameters.each{|p| @params[p.name.to_s] = p}
post_parse_parameters
end
|
#post_initialize ⇒ Object
210
|
# File 'lib/main/base.rb', line 210
def post_initialize() :hook end
|
#post_parse_parameters ⇒ Object
312
|
# File 'lib/main/base.rb', line 312
def post_parse_parameters() :hook end
|
318
|
# File 'lib/main/base.rb', line 318
def post_run() :hook end
|
#pre_initialize ⇒ Object
202
|
# File 'lib/main/base.rb', line 202
def pre_initialize() :hook end
|
#pre_parse_parameters ⇒ Object
302
|
# File 'lib/main/base.rb', line 302
def pre_parse_parameters() :hook end
|
314
|
# File 'lib/main/base.rb', line 314
def pre_run() :hook end
|
315
316
317
|
# File 'lib/main/base.rb', line 315
def run
raise NotImplementedError, 'run not defined'
end
|
#setup_finalizers ⇒ Object
212
213
214
215
216
217
|
# File 'lib/main/base.rb', line 212
def setup_finalizers
@finalizers = finalizers = []
ObjectSpace.define_finalizer(self) do
while((f = finalizers.pop)); f.call; end
end
end
|
#setup_io_redirection ⇒ Object
223
224
225
226
227
|
# File 'lib/main/base.rb', line 223
def setup_io_redirection
self.stdin = @opts['stdin'] || @opts[:stdin] || self.class.stdin
self.stdout = @opts['stdout'] || @opts[:stdout] || self.class.stdout
self.stderr = @opts['stderr'] || @opts[:stderr] || self.class.stderr
end
|
#setup_io_restoration ⇒ Object
249
250
251
252
253
|
# File 'lib/main/base.rb', line 249
def setup_io_restoration
[STDIN, STDOUT, STDERR].each do |io|
dup = io.dup and @finalizers.push lambda{ io.reopen dup }
end
end
|
#setup_logging ⇒ Object
229
230
231
232
|
# File 'lib/main/base.rb', line 229
def setup_logging
log = self.class.logger || stderr
self.logger = log
end
|
#stderr=(io) ⇒ Object
288
289
290
291
292
293
294
295
296
297
298
299
300
|
# File 'lib/main/base.rb', line 288
def stderr= io
unless(defined?(@stderr) and (@stderr == io))
@stderr =
if io.respond_to? 'write'
io
else
fd = open io.to_s, 'w+'
@finalizers.push lambda{ fd.close }
fd
end
STDERR.reopen @stderr rescue($stderr = @stderr)
end
end
|
#stdin=(io) ⇒ Object
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
|
# File 'lib/main/base.rb', line 255
def stdin= io
unless(defined?(@stdin) and (@stdin == io))
@stdin =
if io.respond_to? 'read'
io
else
fd = open io.to_s, 'r+'
@finalizers.push lambda{ fd.close }
fd
end
begin
STDIN.reopen @stdin
rescue
$stdin = @stdin
::Object.const_set 'STDIN', @stdin
end
end
end
|
#stdout=(io) ⇒ Object
274
275
276
277
278
279
280
281
282
283
284
285
286
|
# File 'lib/main/base.rb', line 274
def stdout= io
unless(defined?(@stdout) and (@stdout == io))
@stdout =
if io.respond_to? 'write'
io
else
fd = open io.to_s, 'w+'
@finalizers.push lambda{ fd.close }
fd
end
STDOUT.reopen @stdout rescue($stdout = @stdout)
end
end
|