Module: Command::DSL::Action

Includes:
Formatting
Included in:
Command
Defined in:
lib/command-set/dsl.rb

Overview

The methods available within the DSL::CommandDefinition#action method

The trickiest thing to realize about writing Commands is that a CommandSet is an object that contains several Command subclasses; Commad::setup creates a subclass, and so CommandSet#command does too. It’s when a command is invoked that it’s actually instantiated.

Also note that you can access the arguments of a command as read-only attributes, and you can write to and read from instance variables, which will be local to the invocation of the command. This is especially useful for undo and redo.

Instance Method Summary collapse

Methods included from Formatting

#begin_list, #end_list, #item, #list, #sub_collector

Instance Method Details

#chain(*args) ⇒ Object

It frequently makes sense to offer shortcut chains to the user, or even commands that can only be run as part of another command. Calling chain with either a command class or a command path allows will cause that command to be invoked before returning control to the user.



563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
# File 'lib/command-set/dsl.rb', line 563

def chain(*args)
  setup = CommandSetup.new
  setup.args_hash = Hash === args.last ? args.pop : {}
  setup.command = 
    if args.length == 1
      args = args[0]
      case args
      when Array
        args
      when String
        [args]
      when Symbol
        [args.to_s]
      when Class
        args
      else
        raise CommandException, "Can't chain #{args.inspect}"
      end
    else
      if args.find{|arg| not (String === arg or Symbol === arg)}
        raise CommandException, "Can't chain #{args.inspect}"
      else
        args.map{|arg| arg.to_s}
      end
    end
  subject.chain_of_command.push(setup)
end

#chain_first(klass_or_path, args) ⇒ Object

Like #chain, but interjects the command being chained to the start of the queue, immediately after this command completes.



593
594
595
596
597
598
# File 'lib/command-set/dsl.rb', line 593

def chain_first(klass_or_path, args)
  setup = CommandSetup.new
  setup.command = klass_or_path
  setup.args_hash = args
  subject.chain_of_command.unshift(setup)
end

#defer(deck = nil) ⇒ Object

Stop here and return control to the user. If several commands are chained (c.f. #chain) and the pause is subsequently resumed (StandardCommands::Resume) the rest of the chain (not this command) will be dropped.

Raises:



537
538
539
# File 'lib/command-set/dsl.rb', line 537

def defer(deck = nil) 
  raise ResumeFromOnlyThis, deck
end

#dont_undoObject

Some commands sometimes cause side effects. When evaluating arguments, if you discover that undoing doesn’t make sense, and will be confusing to the user, call dont_undo, and the interpreter will ignore the call for purposes of undoing



513
514
515
516
# File 'lib/command-set/dsl.rb', line 513

def dont_undo
  @should_undo = false
  return nil
end

#interruptableObject

This method is deprecated but remains as a nicety. As it stands, any command can be interrupted at the command line with Ctrl-C, and return to the prompt.



611
612
613
# File 'lib/command-set/dsl.rb', line 611

def interruptable
  yield
end

#pause(deck = nil) ⇒ Object

Stop here. Return control to the user. If several commands are chained (c.f. #chain) and the pause is subsequently resumed (StandardCommands::Resume) the whole chain will be resumed.

Raises:



529
530
531
# File 'lib/command-set/dsl.rb', line 529

def pause(deck = nil)
  raise ResumeFrom, deck
end

#subjectObject

This is how you’ll access the Command::Subject object that’s the interface of every command to the program state.



520
521
522
# File 'lib/command-set/dsl.rb', line 520

def subject
  @subject
end

#task(id) ⇒ Object

Allows for a command to be broken into pieces so that a resume can pick up within a command. The block will be executed normally, but if the command is resumed with a task id, all task blocks until that id will be skipped.



545
546
547
548
549
550
551
552
553
554
# File 'lib/command-set/dsl.rb', line 545

def task(id) #:yield:
  if not @resume_from.nil?
    if @resume_from == id
      @resume_from = nil
    end
    return
  end
  yield if block_given?
  @last_completed_task = id
end

#undo(box) ⇒ Object

Not normally called from within an #action block, this provides the default behavior for an undo (raise an exception)

Raises:



604
605
606
# File 'lib/command-set/dsl.rb', line 604

def undo(box)
  raise CommandException, "#{@name} cannot be undone"
end