Class Tap::Workflow
In: lib/tap/workflow.rb
Parent: Task

Methods

call   define   new  

Attributes

entry_point  [R] 
exit_point  [R] 

Public Class methods

[Source]

     # File lib/tap/workflow.rb, line 98
 98:     def initialize(config={}, app=Tap::App.current)
 99:       super
100:       @entry_point, @exit_point = process
101:     end

Protected Class methods

Defines a task subclass with the specified configurations and process block. During initialization the subclass is instantiated and made accessible through the name method.

Defined tasks may be configured during through config, or directly through the instance; in effect you get tasks with nested configs which can greatly facilitate workflows.

  class AddALetter < Tap::Task
    config :letter, 'a'
    def process(input); input << letter; end
  end

  class AlphabetSoup < Tap::Task
    define :a, AddALetter, {:letter => 'a'}
    define :b, AddALetter, {:letter => 'b'}
    define :c, AddALetter, {:letter => 'c'}

    def process
      sequence(a, b, c)
      [a, c]
    end
  end

  AlphabetSoup.new.process            # => 'abc'

  i = AlphabetSoup.new(:a => {:letter => 'x'}, :b => {:letter => 'y'}, :c => {:letter => 'z'})
  i.process                           # => 'xyz'

  i.config[:a] = {:letter => 'p'}
  i.config[:b][:letter] = 'q'
  i.c.letter = 'r'
  i.process                           # => 'pqr'

Usage

Define is basically the equivalent of:

  class Sample < Tap::Task
    Name = baseclass.subclass(config, &block)

    # accesses an instance of Name
    attr_reader :name

    # register name as a config, but with a
    # non-standard reader and writer
    config :name, {}, {:reader => :name_config, :writer => :name_config=}.merge(options)

    # reader for name.config
    def name_config; ...; end

    # reconfigures name with input
    def name_config=(input); ...; end

    def initialize(*args)
      super
      @name = Name.new(config[:name])
    end
  end

Note the following:

  • define will set a constant like name.camelize
  • the block defines the process method in the subclass
  • three methods are created by define: name, name_config, name_config=

[Source]

    # File lib/tap/workflow.rb, line 73
73:       def define(name, baseclass=Tap::Task, configs={}, options={}, &block)
74:         # define the subclass
75:         subclass = Class.new(baseclass)
76:         configs.each_pair do |key, value|
77:           subclass.send(:config, key, value)
78:         end
79: 
80:         if block_given?
81:           # prevent lazydoc registration of the process method
82:           subclass.registered_methods.delete(:process)
83:           subclass.send(:define_method, :process, &block)
84:         end
85: 
86:         # register documentation
87:         # TODO: register subclass in documentation
88:         options[:desc] ||= Lazydoc.register_caller(Lazydoc::Trailer, 1)
89: 
90:         # add the configuration
91:         nest(name, subclass, {:const_name => name.to_s.camelize}.merge!(options))
92:       end

Public Instance methods

[Source]

     # File lib/tap/workflow.rb, line 103
103:     def call(input)
104:       output = nil
105:       
106:       if exit_point
107:         joins = exit_point.joins
108:       
109:         collector = lambda do |result|
110:           output = result
111:           joins.delete(collector)
112:         end
113:       
114:         joins << collector 
115:       end
116:       
117:       if entry_point
118:         app.exe(entry_point, input)
119:       end
120:       
121:       output
122:     end

[Validate]