You are currently browsing the monthly archive for May 2010.

Already well past 1.0! Tap has evolved a great deal. Many of the big changes are internal — the object APIs are now well-defined and consistent, the environment is MUCH simpler, more powerful, and easier to configure, and there is far less cruft.

I hope to write up more posts but for now an update showcasing ways you can make workflows. The new syntax is much cleaner and more pure.

 
  % tap load abc -: dump
  vs
  % tap run -- load abc --: dump

Commands (ex run) has been dropped. Now the main ARGV given gets split along breaks to get multiple smaller argvs, each of which gets turned into an object. For instance:

 
  ['--', 'load', 'abc']  # the '--' is implied
  ['-:', 'dump']

The leading argument identifies a constant, later args get parsed for configs, and the break itself determines what to do with the remainder. For instance the first set of arguments is equivalent to this:

 
  require 'tap/tasks/load'
  task = Tap::Load.new
  task.enq 'abc'

Breaks all start with a dash. These are various ways of writing the same workflow, each of which will print ‘abc’:

  # as above, '-:' indicates a sequence join
  % tap load abc -: dump

  # the implied '--' means 'enque the next object'
  % tap -- load abc -: dump

  # objects can be defined without enque using '-'
  % tap -- load abc - dump - join 0 1

  # you can reorder as long as you keep the identifiers straight
  % tap - dump -- load abc - join 1 0

  # now use a signal to enque the load task
  % tap - load - dump - join 0 1 -- signal enq 0 abc

  # a little cleaner
  % tap - load - dump - join 0 1 -/enq 0 abc

  # still cleaner
  % tap - load - dump - join 0 1 -@ 0 abc

  # a signal sent to the load task directly
  % tap - load - dump - join 0 1 -/0/enq abc

  # now purely through signals
  % tap -/set 0 load -/set 1 dump -/bld join 0 1 -/0/enq abc

The last example is verbose but indicates the underlying nature of Tap — signals. Tap is now driven entirely by signals such that workflows can be created and driven interactively through a prompt, and later the syntax will translate to the web directly.

  % tap prompt
  /set 0 load
  #<Tap::Tasks::Load:0x1017d9298>
  /set 1 dump
  #<Tap::Tasks::Dump:0x1017b5528>
  /bld join 0 1
  #<Tap::Join:0x1017ac298>
  /enq 0 abc
  #<Tap::Tasks::Load:0x1017d9298>
  /run
  abc
  # future (for example)
  localhost:8080/app/set?var=0&class=load
  localhost:8080/app/set?var=1&class=dump
  ...

Signals mean that workflows can be written out to taprc files:

  [taprc]
  set 0 load
  set 1 dump
  bld join 0 1
  enq abc
  % tap --- taprc
  abc

Objects you load through a tapfile are stored so you can continue to interact with them:

  % tap --- taprc -@ 0 xyz
  abc
  xyz

The latest Tap also adopts and extends the rakish syntax that was Rap (Rap is now gone, FYI).

  [tapfile]
  desc "run a workflow"
  work :example, %q{
    - load
    - dump
    - join 0 1
  }
 
  % tap example abc
  abc

As with a rakefile, tapfiles can define new tasks, with configurations and extended documentation (1.9.1 output):

  [tapfile]
  # This documentation will show up if you run:
  #   % tap sort --help
  
  desc "sort a string by word"
  task :sort, :reverse => false do |config, str|
    words = str.split.sort
    config.reverse ? words.reverse : words
  end
 
  % tap sort 'the swift brown fox' -: dump
  ["brown", "fox", "swift", "the"]
  
  % tap sort 'the swift brown fox' --reverse -: dump
  ["the", "swift", "fox", "brown"]

Tap is much more flexible than it used to be, but you’re still able to do all the things from before like define, package, and distribute tasks as ordinary ruby classes. Check out the documentation for more info.