Taskable
The Taskable module provides a generic task system patterned after Rake, but useable in any code context —not just with the Rake tool. In other words one can create methods with dependencies.
NOTE Unlike methods, tasks can’t take parameters if they are to be used as prerequisites. This capability might be added in the future, but presently syntax limitations make it awkward.
Methods
Public Instance methods
Define description for subsequent task.
[ show source ]
# File lib/facets/more/taskable.rb, line 150 def desc(line=nil) return @last_description unless line @last_description = line.gsub("\n",'') end
Use a description for subsequent task.
[ show source ]
# File lib/facets/more/taskable.rb, line 157 def desc! l = @last_description @last_description = nil l end
List of task names with descriptions.
[ show source ]
# File lib/facets/more/taskable.rb, line 179 def described_tasks instance_tasks.select { |name| instance_task(name).description } end
Access a task.
[ show source ]
# File lib/facets/more/taskable.rb, line 165 def instance_task( name ) instance_task_table[ name.to_sym ] end
List of task names.
[ show source ]
# File lib/facets/more/taskable.rb, line 171 def instance_tasks instance_task_table.keys # t = instance_methods(true).select{ |m| m =~ /^->/ } # t.collect { |e| e[2..-1].to_sym } end
Define a task.
[ show source ]
# File lib/facets/more/taskable.rb, line 191 def task(args, &action) if Hash === args raise ArgumentError, "#{args.size} for 1" if args.size != 1 name, *deps = *(args.to_a.flatten) name = name.to_sym deps = deps.compact.collect{ |e| e.to_sym } else name, deps = args.to_sym, [] end # create task via create core and callable methods. # We do it this way b/c otherwise we'd have to use # instance_eval and then can't ever pass paramaters. if action define_method( "->#{name}", &action ) # core of the task define_method( name ) do # ensure no cycles in the graph and extract call graph #own = (class << self; self; end) # in case there are singletons? todolist = Task::Graph.new( self, name ) todolist.each_strongly_connected_component_from( name ) do |c| send("->#{c}") end end instance_task_table![name] = Task.new( name, self, deps, desc!, &action ) elsif !instance_task_table![name] #define_method( "->#{name}", lambda{} ) # empty action define_method( name ) do # ensure no cycles in the graph and extract call graph #own = (class << self; self; end) # in case there are singletons? todolist = Task::Graph.new( self, name ) todolist.each_strongly_connected_component_from( name ) do |c| send("->#{c}") unless "#{c}" == "#{name}" end end instance_task_table![name] = Task.new( name, self, deps, desc!, &action ) else m = instance_task_table![name] #m.description = desc! # TODO should this apply only if there is an action? m.prerequisite.concat deps unless deps.empty? m end end
List of task names without descriptions.
[ show source ]
# File lib/facets/more/taskable.rb, line 185 def undescribed_tasks instance_tasks.select { |name| ! instance_task(name).description } end