Class: Main::Base

Inherits:
Object show all
Extended by:
DSL
Defined in:
lib/main/base.rb

Defined Under Namespace

Modules: DSL

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DSL

argument, can_has, chunkname, default_options!, environment, has, keyword, mixin, mode, option, parameter

Constructor Details

#initializeBase

Returns a new instance of Base.



306
# File 'lib/main/base.rb', line 306

def initialize() :hook end

Class Method Details

.context(&block) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/main/base.rb', line 131

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



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/main/base.rb', line 111

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!
      #child.wrap_run! unless child.const_defined?(:RUN)
      mode_definitions.each do |name, block|
        klass = 
          create context do
            mode_name name.to_s
            module_eval &block if block
          end
        modes.add klass
      end
    end
  end
end

.fully_qualified_modeObject



153
154
155
156
157
158
159
160
# File 'lib/main/base.rb', line 153

def fully_qualified_mode
  list = []
  ancestors.each do |ancestor|
    break unless ancestor < Base
    list << ancestor.mode_name
  end
  list.reverse[1..-1]
end

.inheritable_fattr(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_fattr name, &block
  block ||= lambda{}
  fattr( 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

override a few fattrs



99
100
101
# File 'lib/main/base.rb', line 99

def mode_name=(value)
  @mode_name = Mode.new value
end

.new(*a, &b) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
# File 'lib/main/base.rb', line 164

def new(*a, &b)
  allocate.instance_eval do
    pre_initialize
    before_initialize
    main_initialize *a, &b
    initialize
    after_initialize
    post_initialize
    self
  end
end

.run(&b) ⇒ Object



162
# File 'lib/main/base.rb', line 162

def run(&b) define_method(:run, &b) end

.usage(*argv, &block) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/main/base.rb', line 103

def usage *argv, &block
  usage! unless defined? @usage 
  return @usage if argv.empty? and block.nil?
  key, value, *ignored = argv
  value = block.call if block
  @usage[key.to_s] = value.to_s
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
      argv.push "--#{ argv.shift }" if argv.first == 'help'
      return mode_run! if mode_given?

      status =
        catch :exit do
          begin

            parse_parameters

            if params['help'] and params['help'].given?
              print usage.to_s
              exit
            end

            pre_run
            before_run
            self.class.const_get(:RUN).bind(self).call(*a, &b)
            after_run
            post_run

            finalize
          rescue Exception => e
            handle_exception e
          end
          nil
        end

      handle_throw status
    end
  end
end

Instance Method Details

#abort(message = 'exit') ⇒ Object

Raises:

  • (SystemExit)


450
451
452
# File 'lib/main/base.rb', line 450

def abort message = 'exit'
  raise SystemExit.new(message)
end

#after_initializeObject



307
# File 'lib/main/base.rb', line 307

def after_initialize() :hook end

#after_parse_parametersObject



413
# File 'lib/main/base.rb', line 413

def after_parse_parameters() :hook end

#after_runObject



421
# File 'lib/main/base.rb', line 421

def after_run() :hook end

#before_initializeObject



298
# File 'lib/main/base.rb', line 298

def before_initialize() :hook end

#before_parse_parametersObject



401
# File 'lib/main/base.rb', line 401

def before_parse_parameters() :hook end

#before_runObject



417
# File 'lib/main/base.rb', line 417

def before_run() :hook end

#fcall(obj, m, *argv, &block) ⇒ Object



484
485
486
487
488
489
490
491
492
493
494
# File 'lib/main/base.rb', line 484

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

#finalizeObject



317
318
319
# File 'lib/main/base.rb', line 317

def finalize
  while((f = @finalizers.pop)); f.call; end
end

#handle_exception(e) ⇒ Object



454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
# File 'lib/main/base.rb', line 454

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
      quiet = ((SystemExit === e and e.message.respond_to?('abort')) or # see main/stdext.rb
              (SystemExit === e and e.message == 'exit'))
      stderr.puts e.message unless quiet
    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



496
497
498
# File 'lib/main/base.rb', line 496

def handle_throw status
  exit(( Integer(status) rescue 0 ))
end

#help!(status = 0) ⇒ Object



445
446
447
448
# File 'lib/main/base.rb', line 445

def help! status = 0
  print usage.to_s
  exit(status)
end

#instance_eval_block(*argv, &block) ⇒ Object



508
509
510
511
512
513
514
515
# File 'lib/main/base.rb', line 508

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



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/main/base.rb', line 331

def logger= log
  unless(defined?(@logger) and @logger == log)
    case log 
      when ::Logger, 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

#main_initialize(argv = ARGV, env = ENV, opts = {}) ⇒ Object



299
300
301
302
303
304
305
# File 'lib/main/base.rb', line 299

def main_initialize argv = ARGV, env = ENV, opts = {}
  @argv, @env, @opts = argv, env, opts
  setup_finalizers
  setup_io_restoration
  setup_io_redirection
  setup_logging
end

#mode_given?Boolean

Returns:

  • (Boolean)


424
425
426
427
428
429
430
431
432
# File 'lib/main/base.rb', line 424

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



433
434
435
436
437
438
439
# File 'lib/main/base.rb', line 433

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

#modesObject



440
441
442
# File 'lib/main/base.rb', line 440

def modes
  self.class.modes
end

#parse_parametersObject



402
403
404
405
406
407
408
409
410
411
412
# File 'lib/main/base.rb', line 402

def parse_parameters
  pre_parse_parameters
  before_parse_parameters

  self.class.parameters.parse self
  @params = Parameter::Table.new
  self.class.parameters.each{|p| @params[p.name.to_s] = p}

  after_parse_parameters
  post_parse_parameters
end

#post_initializeObject



308
# File 'lib/main/base.rb', line 308

def post_initialize() :hook end

#post_parse_parametersObject



414
# File 'lib/main/base.rb', line 414

def post_parse_parameters() :hook end

#post_runObject



422
# File 'lib/main/base.rb', line 422

def post_run() :hook end

#pre_initializeObject



297
# File 'lib/main/base.rb', line 297

def pre_initialize() :hook end

#pre_parse_parametersObject



400
# File 'lib/main/base.rb', line 400

def pre_parse_parameters() :hook end

#pre_runObject



416
# File 'lib/main/base.rb', line 416

def pre_run() :hook end

#runObject

Raises:

  • (NotImplementedError)


418
419
420
# File 'lib/main/base.rb', line 418

def run
  raise NotImplementedError, 'run not defined'
end

#setup_finalizersObject



310
311
312
313
314
315
# File 'lib/main/base.rb', line 310

def setup_finalizers
  @finalizers = finalizers = []
  ObjectSpace.define_finalizer(self) do
    while((f = finalizers.pop)); f.call; end
  end
end

#setup_io_redirectionObject



321
322
323
324
325
# File 'lib/main/base.rb', line 321

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_restorationObject



347
348
349
350
351
# File 'lib/main/base.rb', line 347

def setup_io_restoration
  [STDIN, STDOUT, STDERR].each do |io|
    dup = io.dup and @finalizers.push lambda{ io.reopen dup rescue nil }
  end
end

#setup_loggingObject



327
328
329
330
# File 'lib/main/base.rb', line 327

def setup_logging
  log = self.class.logger || stderr
  self.logger = log
end

#stderr=(io) ⇒ Object



386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/main/base.rb', line 386

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



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/main/base.rb', line 353

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



372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/main/base.rb', line 372

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