(simpler than the one from active_support)
# File lib/ruote/util/misc.rb, line 122 def self.constantize (s) s.split('::').inject(Object) { |c, n| n == '' ? c : c.const_get(n) } end
# File lib/ruote/engine/process_status.rb, line 258 def self.decompose_tree (t, pos='0', h={}) h[pos] = t[0, 2] t[2].each_with_index { |c, i| decompose_tree(c, "#{pos}_#{i}", h) } h end
Not really a parser, more an AST builder.
pdef = Ruote.define :name => 'take_out_garbage' do
sequence do
take_out_regular_garbage
take_out_glass
take_out_paper
end
end
engine.launch(pdef)
# File lib/ruote/parser/ruby_dsl.rb, line 40 def self.define (*attributes, &block) RubyDsl.create_branch('define', attributes, &block) end
Performs 'dollar substitution' on a piece of text with as input a flow expression and a workitem (fields and variables).
# File lib/ruote/util/dollar.rb, line 36 def self.dosub (text, flow_expression, workitem) # # patch by Nick Petrella (2008/03/20) # if text.is_a?(String) Rufus.dsub(text, FlowDict.new(flow_expression, workitem)) elsif text.is_a?(Array) text.collect { |e| dosub(e, flow_expression, workitem) } elsif text.is_a?(Hash) text.inject({}) do |h, (k, v)| h[dosub(k, flow_expression, workitem)] = dosub(v, flow_expression, workitem) h end else text end end
Deep object duplication
# File lib/ruote/util/misc.rb, line 48 def self.fulldup (object) return object.fulldup if object.respond_to?(:fulldup) # trusting client objects providing a fulldup() implementation # Tomaso Tosolini 2007.12.11 begin return Marshal.load(Marshal.dump(object)) # as soon as possible try to use that Marshal technique # it's quite fast rescue TypeError => te end #if object.is_a?(REXML::Element) # d = REXML::Document.new object.to_s # return d if object.kind_of?(REXML::Document) # return d.root #end # avoiding "TypeError: singleton can't be dumped" o = object.class.allocate # some kind of collection ? if object.is_a?(Array) object.each { |i| o << fulldup(i) } elsif object.is_a?(Hash) object.each { |k, v| o[fulldup(k)] = fulldup(v) } end # duplicate the attributes of the object object.instance_variables.each do |v| value = object.instance_variable_get(v) value = fulldup(value) begin o.instance_variable_set(v, value) rescue Exception => e # ignore, must be readonly end end o end
Waiting for a better implementation of it in rufus-scheduler 2.0.4
# File lib/ruote/util/time.rb, line 90 def self.is_cron_string (s) ss = s.split(' ') return false if ss.size < 5 || ss.size > 6 return false if s.match(/\d{4}/) true end
# File lib/ruote/subprocess.rb, line 63 def self.is_pos_tree? (a) a.is_a?(Array) && a.size == 2 && a[0].is_a?(String) && is_tree?(a[1]) end
# File lib/ruote/subprocess.rb, line 58 def self.is_tree? (a) a.is_a?(Array) && a[1].is_a?(Hash) && a.size == 3 end
Returns true if the string seems to correpond to a URI
TODO : wouldn't it be better to simply use URI.parse() ?
# File lib/ruote/util/misc.rb, line 97 def self.is_uri? (s) s && (s.index('/') || s.match(/\.[^ ]+$/)) end
h = { 'a' => { 'b' => [ 1, 3, 4 ] } }
p Ruote.lookup(h, 'a.b.1') # => 3
# File lib/ruote/util/lookup.rb, line 32 def Ruote.lookup (collection, key, container_lookup=false) key, rest = pop_key(key) value = flookup(collection, key) return [ key, collection ] if container_lookup && rest.size == 0 return [ rest.first, value ] if container_lookup && rest.size == 1 return value if rest.size == 0 return nil if value == nil lookup(value, rest) end
This method is used by the 'subprocess' expression and by the EngineParticipant.
# File lib/ruote/subprocess.rb, line 35 def self.lookup_subprocess (fexp, ref) val = fexp.lookup_variable(ref) # a classical subprocess stored in a variable ? return [ '0', val ] if is_tree?(val) return val if is_pos_tree?(val) # maybe subprocess :ref => 'uri' subtree = fexp.context.parser.parse(ref) rescue nil _, subtree = Ruote::Exp::DefineExpression.reorganize(subtree) if subtree && Ruote::Exp::DefineExpression.is_definition?(subtree) return [ '0', subtree ] if is_tree?(subtree) # no luck ... raise "no subprocess named '#{ref}' found" end
Tries to return an Integer or a Float from the given input. Returns
# File lib/ruote/util/misc.rb, line 111 def self.narrow_to_number (o) return o if [ Fixnum, Bignum, Float ].include?(o.class) s = o.to_s (s.index('.') ? Float(s) : Integer(s)) rescue nil end
Returns a neutralized version of s, suitable as a filename.
# File lib/ruote/util/misc.rb, line 104 def self.neutralize (s) s.to_s.strip.gsub(/[ \/:;\*\\\+\?]/, '_') end
Returns a parsable representation of the UTC time now.
like "2009/11/23 11:11:50.947109 UTC"
# File lib/ruote/util/time.rb, line 57 def self.now_to_utc_s time_to_utc_s(Time.now) end
Prints the current call stack to stdout
# File lib/ruote/util/misc.rb, line 38 def self.p_caller (*msg) puts puts " == #{msg.inspect} ==" caller(1).each { |l| puts " #{l}" } puts end
Same as Ruote.define()
pdef = Ruote.process_definition :name => 'take_out_garbage' do
sequence do
take_out_regular_garbage
take_out_paper
end
end
engine.launch(pdef)
# File lib/ruote/parser/ruby_dsl.rb, line 56 def self.process_definition (*attributes, &block) define(*attributes, &block) end
# File lib/ruote/engine/process_status.rb, line 265 def self.recompose_tree (h, pos='0') t = h[pos] return nil unless t t << [] i = 0 loop do tt = recompose_tree(h, "#{pos}_#{i}") break unless tt t.last << tt i = i + 1 end t end
Turns a date or a duration to a Time object pointing AT a point in time...
(my prose is weak)
# File lib/ruote/util/time.rb, line 66 def self.s_to_at (s) at = if s.index(' ') # # date Rufus.to_ruby_time(s)# rescue nil else # # duration Time.now.utc.to_f + Rufus.parse_time_string(s) end case at when DateTime then at.to_time.utc when Float then Time.at(at).utc else at end end
h = { 'customer' => { 'name' => 'alpha' } }
Ruote.set(h, 'customer.name', 'bravo')
h #=> { 'customer' => { 'name' => 'bravo' } }
# File lib/ruote/util/lookup.rb, line 51 def Ruote.set (collection, key, value) k, c = lookup(collection, key, true) if c k = k.to_i if c.is_a?(Array) c[k] = value else collection[key] = value end end
A shorter shortcut for
Ruote::FlowExpressionId.to_storage_id(fei)
# File lib/ruote/fei.rb, line 46 def self.sid (fei) Ruote::FlowExpressionId.to_storage_id(fei) end
Produces the UTC string representation of a Time
like "2009/11/23 11:11:50.947109 UTC"
# File lib/ruote/util/time.rb, line 48 def self.time_to_utc_s (t) "#{t.utc.strftime('%Y-%m-%d %H:%M:%S')}.#{sprintf('%06d', t.usec)} UTC" end
A shortcut for
Ruote::FlowExpressionId.to_storage_id(fei)
# File lib/ruote/fei.rb, line 37 def self.to_storage_id (fei) Ruote::FlowExpressionId.to_storage_id(fei) end
Similar in purpose to Ruote.define and Ruote.process_definition but instead of returning a [process] definition, returns the tree.
tree = Ruote.process_definition :name => 'take_out_garbage' do
sequence do
take_out_regular_garbage
take_out_paper
end
end
p tree
# => [ 'sequence', {}, [ [ 'take_out_regular_garbage', {}, [] ], [ 'take_out_paper', {}, [] ] ] ],
This is useful when modifying a process instance via methods like re_apply :
engine.re_apply(
fei,
:tree => Ruote.to_tree {
sequence do
participant 'alfred'
participant 'bob'
end
})
#
# cancels the segment of process at fei and replaces it with
# a simple alfred-bob sequence.
# File lib/ruote/parser/ruby_dsl.rb, line 88 def self.to_tree (&block) RubyDsl.create_branch('x', {}, &block).last.first end
Turns a process definition tree to a graphviz dot representation.
# File lib/ruote/tree_dot.rb, line 32 def self.tree_to_dot (tree, name='ruote process definition') s = "digraph \"#{name}\" {\n" s << branch_to_dot('0', tree).join("\n") s << "\n}\n" end
Turning a tree into a numbered string view
require 'ruote/util/tree'
require 'ruote/parser/ruby_dsl'
pdef = Ruote.process_definition :name => 'def0' do
sequence do
alpha
bravo
end
end
p pdef
# => ["define", {"name"=>"def0"}, [["sequence", {}, [["alpha", {}, []], ["bravo", {}, []]]]]]
puts Ruote.tree_to_s(pdef)
# =>
# 0 define {"name"=>"def0"}
# 0_0 sequence {}
# 0_0_0 alpha {}
# 0_0_1 bravo {}
# File lib/ruote/util/tree.rb, line 50 def Ruote.tree_to_s (tree, expid='0') d = expid.split('_').size - 1 s = "#{' ' * d * 2}#{expid} #{tree[0]} #{tree[1].inspect}\n" tree[2].each_with_index { |t, i| s << tree_to_s(t, "#{expid}_#{i}") } s end
h = { 'customer' => { 'name' => 'alpha', 'rank' => '1st' } } r = Ruote.unset(h, 'customer.rank')
h # => { 'customer' => { 'name' => 'alpha' } } r # => '1st'
# File lib/ruote/util/lookup.rb, line 69 def Ruote.unset (collection, key) k, c = lookup(collection, key, true) return collection.delete(key) unless c if c.is_a?(Array) c.delete_at(Integer(k)) rescue nil else c.delete(k) end end
# File lib/ruote/tree_dot.rb, line 41 def self.branch_to_dot (expid, exp) [ " \"#{expid}\" "+ "[ label = \"#{exp[0]} #{exp[1].inspect.gsub("\"", "'")}\" ];" ] + children_to_dot(expid, exp) end
# File lib/ruote/tree_dot.rb, line 50 def self.children_to_dot (expid, exp) exp_name = exp[0] child_count = exp[2].size i = -1 a = exp[2].collect do |child| i += 1 branch_to_dot("#{expid}_#{i}", child) end if child_count > 0 # there are children if ] concurrence if ].include?(exp_name) (0..child_count - 1).each do |i| a << " \"#{expid}\" -> \"#{expid}_#{i}\";" a << " \"#{expid}_#{i}\" -> \"#{expid}\";" end else a << " \"#{expid}\" -> \"#{expid}_0\";" a << " \"#{expid}_#{child_count -1}\" -> \"#{expid}\";" (0..child_count - 2).each do |i| a << " \"#{expid}_#{i}\" -> \"#{expid}_#{i + 1}\";" end end end a end
# File lib/ruote/util/lookup.rb, line 101 def Ruote.flookup (collection, key) value = (collection[key] rescue nil) if value == nil and key.is_a?(Fixnum) value = (collection[key.to_s] rescue nil) end value end
Generated with the Darkfish Rdoc Generator 2.