trailblazer-activity 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop-https---raw-githubusercontent-com-trailblazer-meta-master-rubocop-yml +101 -0
- data/.rubocop.yml +4 -13
- data/.rubocop_todo.yml +474 -476
- data/.travis.yml +3 -2
- data/CHANGES.md +10 -0
- data/Gemfile +5 -4
- data/README.md +2 -0
- data/Rakefile +1 -1
- data/lib/trailblazer/activity.rb +29 -92
- data/lib/trailblazer/activity/circuit.rb +74 -0
- data/lib/trailblazer/activity/config.rb +4 -6
- data/lib/trailblazer/activity/introspect.rb +33 -129
- data/lib/trailblazer/activity/present.rb +14 -39
- data/lib/trailblazer/activity/schema.rb +13 -0
- data/lib/trailblazer/activity/schema/implementation.rb +10 -0
- data/lib/trailblazer/activity/schema/intermediate.rb +94 -0
- data/lib/trailblazer/activity/structures.rb +43 -43
- data/lib/trailblazer/activity/task_wrap.rb +29 -16
- data/lib/trailblazer/activity/task_wrap/call_task.rb +4 -4
- data/lib/trailblazer/activity/task_wrap/inject.rb +37 -0
- data/lib/trailblazer/activity/task_wrap/pipeline.rb +55 -0
- data/lib/trailblazer/activity/task_wrap/runner.rb +10 -19
- data/lib/trailblazer/activity/task_wrap/variable_mapping.rb +25 -97
- data/lib/trailblazer/activity/testing.rb +64 -22
- data/lib/trailblazer/activity/trace.rb +88 -41
- data/lib/trailblazer/activity/version.rb +4 -2
- data/trailblazer-activity.gemspec +5 -9
- metadata +18 -55
- data/lib/trailblazer/activity/dsl/add_task.rb +0 -22
- data/lib/trailblazer/activity/dsl/helper.rb +0 -68
- data/lib/trailblazer/activity/dsl/magnetic.rb +0 -36
- data/lib/trailblazer/activity/dsl/magnetic/builder.rb +0 -101
- data/lib/trailblazer/activity/dsl/magnetic/builder/default_normalizer.rb +0 -26
- data/lib/trailblazer/activity/dsl/magnetic/builder/fast_track.rb +0 -118
- data/lib/trailblazer/activity/dsl/magnetic/builder/normalizer.rb +0 -113
- data/lib/trailblazer/activity/dsl/magnetic/builder/path.rb +0 -105
- data/lib/trailblazer/activity/dsl/magnetic/builder/railway.rb +0 -97
- data/lib/trailblazer/activity/dsl/magnetic/builder/state.rb +0 -58
- data/lib/trailblazer/activity/dsl/magnetic/finalizer.rb +0 -51
- data/lib/trailblazer/activity/dsl/magnetic/generate.rb +0 -62
- data/lib/trailblazer/activity/dsl/magnetic/merge.rb +0 -16
- data/lib/trailblazer/activity/dsl/magnetic/process_options.rb +0 -76
- data/lib/trailblazer/activity/dsl/magnetic/structure/alterations.rb +0 -44
- data/lib/trailblazer/activity/dsl/magnetic/structure/plus_poles.rb +0 -85
- data/lib/trailblazer/activity/dsl/magnetic/structure/polarization.rb +0 -23
- data/lib/trailblazer/activity/dsl/record.rb +0 -11
- data/lib/trailblazer/activity/dsl/schema/dependencies.rb +0 -46
- data/lib/trailblazer/activity/dsl/schema/sequence.rb +0 -46
- data/lib/trailblazer/activity/dsl/strategy/build_state.rb +0 -32
- data/lib/trailblazer/activity/dsl/strategy/fast_track.rb +0 -24
- data/lib/trailblazer/activity/dsl/strategy/path.rb +0 -26
- data/lib/trailblazer/activity/dsl/strategy/plan.rb +0 -36
- data/lib/trailblazer/activity/dsl/strategy/railway.rb +0 -23
- data/lib/trailblazer/activity/interface.rb +0 -16
- data/lib/trailblazer/activity/task_wrap/merge.rb +0 -23
- data/lib/trailblazer/activity/task_wrap/trace.rb +0 -44
- data/lib/trailblazer/circuit.rb +0 -71
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
# 0.8.0
|
2
|
+
|
3
|
+
* Separate the [DSL](https://github.com/trailblazer/trailblazer-activity-dsl-linear) from the runtime code. The latter sits in this gem.
|
4
|
+
* Separate the runtime {Activity} from its compilation, which happens through {Intermediate} (the structure) and {Implementation} (the runtime implementation) now.
|
5
|
+
* Introduce {Pipeline} which is a simpler and much fast type of activity, mostly for the taskWrap.
|
6
|
+
|
7
|
+
# 0.7.2
|
8
|
+
|
9
|
+
* When recording DSL calls, use the `object_id` as key, so cloned methods are considered as different recordings.
|
10
|
+
|
1
11
|
# 0.7.1
|
2
12
|
|
3
13
|
* Alias `Trace.call` to `Trace.invoke` for consistency.
|
data/Gemfile
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in workflow.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem "minitest-line"
|
7
6
|
gem "benchmark-ips"
|
7
|
+
gem "minitest-line"
|
8
8
|
|
9
9
|
gem "rubocop", require: false
|
10
10
|
|
11
|
-
gem "trailblazer-
|
12
|
-
|
11
|
+
# gem "trailblazer-context", path: "../trailblazer-context"
|
12
|
+
gem "trailblazer-developer", path: "../trailblazer-developer"
|
13
|
+
# gem "trailblazer-developer", github: "trailblazer/trailblazer-developer", branch: "exception-tracing"
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Activity
|
2
2
|
|
3
|
+
implements Intermediate, Implementation, compiler and `Activity::Implementation`, Activity::Interface
|
4
|
+
|
3
5
|
The `activity` gem brings a light-weight DSL to define business processes, and the runtime logic to run those activities.
|
4
6
|
|
5
7
|
A process is a set of arbitrary pieces of logic you define, chained together and put into a meaningful context by an activity. Activity lets you focus on the implementation of steps while Trailblazer takes care of the control flow.
|
data/Rakefile
CHANGED
data/lib/trailblazer/activity.rb
CHANGED
@@ -1,123 +1,60 @@
|
|
1
1
|
module Trailblazer
|
2
|
-
|
3
|
-
|
2
|
+
# This is DSL-independent code, focusing only on run-time.
|
3
|
+
class Activity
|
4
|
+
# include Activity::Interface # TODO
|
4
5
|
|
5
|
-
def initialize(
|
6
|
-
|
7
|
-
|
8
|
-
@initial_state = State::Config.build(
|
9
|
-
builder: builder,
|
10
|
-
options: options,
|
11
|
-
adds: adds,
|
12
|
-
circuit: circuit,
|
13
|
-
outputs: outputs,
|
14
|
-
)
|
15
|
-
|
16
|
-
include *options[:extend] # include the DSL methods.
|
17
|
-
include PublicAPI
|
18
|
-
end
|
19
|
-
|
20
|
-
# Injects the initial configuration into the module defining a new activity.
|
21
|
-
def extended(extended)
|
22
|
-
super
|
23
|
-
extended.instance_variable_set(:@state, initial_state)
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
module Inspect
|
28
|
-
def inspect
|
29
|
-
"#<Trailblazer::Activity: {#{name || self[:options][:name]}}>"
|
30
|
-
end
|
31
|
-
|
32
|
-
alias_method :to_s, :inspect
|
6
|
+
def initialize(schema)
|
7
|
+
@schema = schema
|
33
8
|
end
|
34
9
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
def_delegators :@builder, :Path
|
41
|
-
def_delegators DSL, :Output, :End, :Subprocess, :Track
|
42
|
-
|
43
|
-
def Path(*args, &block)
|
44
|
-
self[:builder].Path(*args, &block)
|
45
|
-
end
|
10
|
+
def call(args, circuit_options={})
|
11
|
+
@schema[:circuit].(
|
12
|
+
args,
|
13
|
+
circuit_options.merge(activity: self)
|
14
|
+
)
|
46
15
|
end
|
47
16
|
|
48
|
-
# Reader and writer method for
|
17
|
+
# Reader and writer method for an Activity.
|
49
18
|
# The writer {dsl[:key] = "value"} exposes immutable behavior and will replace the old
|
50
19
|
# @state with a new, modified copy.
|
51
20
|
#
|
52
|
-
# Always use the
|
21
|
+
# Always use the accessors to avoid leaking state to other components
|
53
22
|
# due to mutable write operations.
|
54
|
-
|
55
|
-
|
56
|
-
@state = State::Config.send(:[]=, @state, *args)
|
57
|
-
end
|
58
|
-
|
59
|
-
def [](*args)
|
60
|
-
State::Config[@state, *args]
|
61
|
-
end
|
23
|
+
def [](*key)
|
24
|
+
@schema[:config][*key]
|
62
25
|
end
|
63
26
|
|
64
|
-
|
65
|
-
|
66
|
-
# Later, this module is `extended` in Path, Railway and FastTrack, and
|
67
|
-
# imports the DSL methods as class methods.
|
68
|
-
module PublicAPI
|
69
|
-
include Accessor
|
70
|
-
|
71
|
-
require "trailblazer/activity/dsl/add_task"
|
72
|
-
include DSL::AddTask
|
73
|
-
|
74
|
-
require "trailblazer/activity/interface"
|
75
|
-
include Activity::Interface # DISCUSS
|
76
|
-
|
77
|
-
include DSLHelper # DISCUSS
|
78
|
-
|
79
|
-
include Activity::Inspect # DISCUSS
|
80
|
-
|
81
|
-
require "trailblazer/activity/dsl/magnetic/merge"
|
82
|
-
include Magnetic::Merge # Activity#merge!
|
83
|
-
|
84
|
-
# @private Note that {Activity.call} is considered private until the public API is stable.
|
85
|
-
def call(args, circuit_options={})
|
86
|
-
self[:circuit].( args, circuit_options.merge(activity: self) )
|
87
|
-
end
|
27
|
+
def to_h
|
28
|
+
@schema
|
88
29
|
end
|
89
30
|
|
31
|
+
def inspect
|
32
|
+
%{#<Trailblazer::Activity:0x#{object_id}>}
|
33
|
+
end
|
90
34
|
end # Activity
|
91
35
|
end
|
92
36
|
|
93
|
-
require "trailblazer/
|
37
|
+
# require "trailblazer/activity/interface"
|
94
38
|
require "trailblazer/activity/structures"
|
39
|
+
require "trailblazer/activity/schema"
|
40
|
+
require "trailblazer/activity/schema/implementation"
|
41
|
+
require "trailblazer/activity/schema/intermediate"
|
42
|
+
require "trailblazer/activity/circuit"
|
95
43
|
require "trailblazer/activity/config"
|
96
44
|
|
97
|
-
require "trailblazer/activity/dsl/strategy/build_state"
|
98
|
-
require "trailblazer/activity/dsl/strategy/path"
|
99
|
-
require "trailblazer/activity/dsl/strategy/plan"
|
100
|
-
require "trailblazer/activity/dsl/strategy/railway"
|
101
|
-
require "trailblazer/activity/dsl/strategy/fast_track"
|
102
|
-
|
103
45
|
require "trailblazer/activity/task_wrap"
|
46
|
+
require "trailblazer/activity/task_wrap/pipeline"
|
104
47
|
require "trailblazer/activity/task_wrap/call_task"
|
105
|
-
require "trailblazer/activity/task_wrap/trace"
|
106
48
|
require "trailblazer/activity/task_wrap/runner"
|
107
|
-
require "trailblazer/activity/task_wrap/merge"
|
108
49
|
require "trailblazer/activity/task_wrap/variable_mapping"
|
50
|
+
require "trailblazer/activity/task_wrap/inject"
|
109
51
|
|
110
52
|
require "trailblazer/activity/trace"
|
111
53
|
require "trailblazer/activity/present"
|
112
54
|
|
113
55
|
require "trailblazer/activity/introspect"
|
56
|
+
require "trailblazer/option"
|
57
|
+
require "trailblazer/context"
|
58
|
+
require "trailblazer/activity/task_builder"
|
114
59
|
|
115
|
-
require "trailblazer/activity/dsl/magnetic/builder/state"
|
116
|
-
require "trailblazer/activity/dsl/magnetic" # the "magnetic" DSL
|
117
|
-
|
118
|
-
require "trailblazer/activity/dsl/schema/sequence"
|
119
|
-
require "trailblazer/activity/dsl/schema/dependencies"
|
120
|
-
|
121
|
-
require "trailblazer/activity/dsl/magnetic/builder/normalizer" # DISCUSS: name and location are odd. This one uses Activity ;)
|
122
60
|
|
123
|
-
require "trailblazer/activity/dsl/record"
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Trailblazer
|
2
|
+
class Activity
|
3
|
+
# Running a Circuit instance will run all tasks sequentially depending on the former's result.
|
4
|
+
# Each task is called and retrieves the former task's return values.
|
5
|
+
#
|
6
|
+
# Note: Please use #Activity as a public circuit builder.
|
7
|
+
#
|
8
|
+
# @param map [Hash] Defines the wiring.
|
9
|
+
# @param stop_events [Array] Tasks that stop execution of the circuit.
|
10
|
+
#
|
11
|
+
# result = circuit.(start_at, *args)
|
12
|
+
#
|
13
|
+
# @see Activity
|
14
|
+
# @api semi-private
|
15
|
+
#
|
16
|
+
# This is the "pipeline operator"'s implementation.
|
17
|
+
class Circuit
|
18
|
+
def initialize(map, stop_events, start_task:, name: nil)
|
19
|
+
@map = map
|
20
|
+
@stop_events = stop_events
|
21
|
+
@name = name
|
22
|
+
@start_task = start_task
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param args [Array] all arguments to be passed to the task's `call`
|
26
|
+
# @param task [callable] task to call
|
27
|
+
Run = ->(task, args, **circuit_options) { task.(args, **circuit_options) }
|
28
|
+
|
29
|
+
# Runs the circuit until we hit a stop event.
|
30
|
+
#
|
31
|
+
# This method throws exceptions when the returned value of a task doesn't match
|
32
|
+
# any wiring.
|
33
|
+
#
|
34
|
+
# @param task An event or task of this circuit from where to start
|
35
|
+
# @param options anything you want to pass to the first task
|
36
|
+
# @param flow_options Library-specific flow control data
|
37
|
+
# @return [last_signal, options, flow_options, *args]
|
38
|
+
#
|
39
|
+
# NOTE: returned circuit_options are discarded when calling the runner.
|
40
|
+
def call(args, start_task: @start_task, runner: Run, **circuit_options)
|
41
|
+
circuit_options = circuit_options.merge( runner: runner ).freeze # TODO: set the :runner option via arguments_for_call to save the merge?
|
42
|
+
task = start_task
|
43
|
+
|
44
|
+
loop do
|
45
|
+
last_signal, args, _discarded_circuit_options = runner.(
|
46
|
+
task,
|
47
|
+
args,
|
48
|
+
circuit_options
|
49
|
+
)
|
50
|
+
|
51
|
+
# Stop execution of the circuit when we hit a stop event (< End). This could be an task's End or Suspend.
|
52
|
+
return [ last_signal, args ] if @stop_events.include?(task) # DISCUSS: return circuit_options here?
|
53
|
+
|
54
|
+
task = next_for(task, last_signal) or raise IllegalSignalError.new("<#{@name}>[#{task}][ #{last_signal.inspect} ]")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the circuit's components.
|
59
|
+
def to_h
|
60
|
+
{ map: @map, end_events: @stop_events, start_task: @start_task }
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def next_for(last_task, signal)
|
66
|
+
outputs = @map[last_task]
|
67
|
+
outputs[signal]
|
68
|
+
end
|
69
|
+
|
70
|
+
class IllegalSignalError < RuntimeError
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -3,12 +3,10 @@ module Trailblazer
|
|
3
3
|
# Compile-time
|
4
4
|
#
|
5
5
|
# DISCUSS: we could replace parts with Hamster::Hash.
|
6
|
-
|
7
|
-
|
8
|
-
Hash[ variables.collect { |k,v| [k, v.freeze] } ].freeze
|
9
|
-
end
|
6
|
+
module Config
|
7
|
+
module_function
|
10
8
|
|
11
|
-
def
|
9
|
+
def set(state, *args)
|
12
10
|
if args.size == 2
|
13
11
|
key, value = *args
|
14
12
|
|
@@ -25,7 +23,7 @@ module Trailblazer
|
|
25
23
|
state
|
26
24
|
end
|
27
25
|
|
28
|
-
def
|
26
|
+
def get(state, *args)
|
29
27
|
directive, key = *args
|
30
28
|
|
31
29
|
return state[directive] if args.size == 1
|
@@ -1,18 +1,22 @@
|
|
1
1
|
module Trailblazer
|
2
|
-
class Activity
|
3
|
-
#
|
4
|
-
#
|
2
|
+
class Activity
|
3
|
+
# The Introspect API abstracts internals about circuits and provides a convenient API
|
4
|
+
# to third-parties such as tracing, rendering activities, etc.
|
5
5
|
module Introspect
|
6
6
|
def self.Graph(*args)
|
7
7
|
Graph.new(*args)
|
8
8
|
end
|
9
9
|
|
10
|
+
# TODO: order of step/fail/pass in Node would be cool to have
|
11
|
+
|
10
12
|
# @private This API is still under construction.
|
11
13
|
class Graph
|
12
14
|
def initialize(activity)
|
13
15
|
@activity = activity
|
14
|
-
@
|
15
|
-
@
|
16
|
+
@schema = activity.to_h or raise
|
17
|
+
@circuit = @schema[:circuit]
|
18
|
+
@map = @circuit.to_h[:map]
|
19
|
+
@configs = @schema[:nodes]
|
16
20
|
end
|
17
21
|
|
18
22
|
def find(id=nil, &block)
|
@@ -20,148 +24,48 @@ module Trailblazer
|
|
20
24
|
find_with_block(&block)
|
21
25
|
end
|
22
26
|
|
27
|
+
def collect(strategy: :circuit, &block)
|
28
|
+
@map.keys.each_with_index.collect { |task, i| yield find_with_block { |node| node.task==task }, i }
|
29
|
+
end
|
30
|
+
|
31
|
+
def stop_events
|
32
|
+
@circuit.to_h[:end_events]
|
33
|
+
end
|
34
|
+
|
23
35
|
private
|
24
36
|
|
25
37
|
def find_by_id(id)
|
26
|
-
|
27
|
-
|
28
|
-
Node(triplett[1], id, triplett[0])
|
38
|
+
node = @configs.find { |node| node.id == id } or return
|
39
|
+
node_for(node)
|
29
40
|
end
|
30
41
|
|
31
42
|
def find_with_block(&block)
|
32
|
-
|
33
|
-
return nil unless adds
|
43
|
+
existing = @configs.find { |node| yield Node(node.task, node.id, node.outputs, node.data) } or return
|
34
44
|
|
35
|
-
(
|
45
|
+
node_for(existing)
|
46
|
+
end
|
36
47
|
|
37
|
-
|
48
|
+
def node_for(node_attributes)
|
49
|
+
Node(node_attributes.task, node_attributes.id, node_attributes.outputs, outgoings_for(node_attributes), node_attributes.data)
|
38
50
|
end
|
39
51
|
|
40
52
|
def Node(*args)
|
41
53
|
Node.new(*args).freeze
|
42
54
|
end
|
43
55
|
|
44
|
-
Node
|
45
|
-
|
46
|
-
|
56
|
+
Node = Struct.new(:task, :id, :outputs, :outgoings, :data)
|
57
|
+
Outgoing = Struct.new(:output, :task)
|
47
58
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
circuit = activity.to_h[:circuit]
|
52
|
-
circuit_hash = circuit.to_h[:map]
|
53
|
-
|
54
|
-
locals = circuit_hash.collect do |task, connections|
|
55
|
-
[
|
56
|
-
yield(task, connections),
|
57
|
-
*options[:recursive] && task.is_a?(Activity::Interface) ? collect(task, options, &block) : []
|
58
|
-
]
|
59
|
-
end.flatten(1)
|
60
|
-
end
|
59
|
+
def outgoings_for(node)
|
60
|
+
outputs = node.outputs
|
61
|
+
connections = @map[node.task]
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
match = proc.inspect.match(/(\w+)>$/)
|
66
|
-
|
67
|
-
%{#<TaskBuilder{.#{match[1]}}>}
|
68
|
-
end
|
69
|
-
|
70
|
-
# FIXME: clean up that shit below.
|
71
|
-
|
72
|
-
# render
|
73
|
-
def self.Cct(circuit, **options)
|
74
|
-
circuit_hash( circuit.to_h[:map], **options )
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.circuit_hash(circuit_hash, show_ids:false, **options)
|
78
|
-
content =
|
79
|
-
circuit_hash.collect do |task, connections|
|
80
|
-
conns = connections.collect do |signal, target|
|
81
|
-
" {#{signal}} => #{inspect_with_matcher(target, **options)}"
|
82
|
-
end
|
83
|
-
|
84
|
-
[ inspect_with_matcher(task, **options), conns.join("\n") ]
|
63
|
+
connections.collect do |signal, target|
|
64
|
+
output = outputs.find { |out| out.signal == signal }
|
65
|
+
Outgoing.new(output, target)
|
85
66
|
end
|
86
|
-
|
87
|
-
content = content.join("\n")
|
88
|
-
|
89
|
-
return "\n#{content}" if show_ids
|
90
|
-
return "\n#{content}".gsub(/0x\w+/, "0x").gsub(/0.\d+/, "0.")
|
91
|
-
end
|
92
|
-
|
93
|
-
def self.Ends(activity)
|
94
|
-
end_events = activity.to_h[:end_events]
|
95
|
-
ends = end_events.collect { |evt| inspect_end(evt) }.join(",")
|
96
|
-
"[#{ends}]".gsub(/\d\d+/, "")
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
|
-
def self.Outputs(outputs)
|
101
|
-
outputs.collect { |semantic, output| "#{semantic}=> (#{output.signal}, #{output.semantic})" }.
|
102
|
-
join("\n").gsub(/0x\w+/, "").gsub(/\d\d+/, "")
|
103
|
-
end
|
104
|
-
|
105
|
-
# If Ruby had pattern matching, this function wasn't necessary.
|
106
|
-
def self.inspect_with_matcher(task, inspect_task: method(:inspect_task), inspect_end: method(:inspect_end))
|
107
|
-
return inspect_task.(task) unless task.kind_of?(Trailblazer::Activity::End)
|
108
|
-
inspect_end.(task)
|
109
|
-
end
|
110
|
-
|
111
|
-
def self.inspect_task(task)
|
112
|
-
task.inspect
|
113
|
-
end
|
114
|
-
|
115
|
-
def self.inspect_end(task)
|
116
|
-
class_name = strip(task.class)
|
117
|
-
options = task.to_h
|
118
|
-
|
119
|
-
"#<#{class_name}/#{options[:semantic].inspect}>"
|
120
|
-
end
|
121
|
-
|
122
|
-
def self.strip(string)
|
123
|
-
string.to_s.sub("Trailblazer::Activity::", "")
|
67
|
+
end
|
124
68
|
end
|
125
69
|
end #Introspect
|
126
70
|
end
|
127
|
-
|
128
|
-
module Activity::Magnetic
|
129
|
-
module Introspect
|
130
|
-
def self.seq(activity)
|
131
|
-
adds = activity.instance_variable_get(:@adds)
|
132
|
-
tripletts = Builder::Finalizer.adds_to_tripletts(adds)
|
133
|
-
|
134
|
-
Seq(tripletts)
|
135
|
-
end
|
136
|
-
|
137
|
-
def self.cct(builder)
|
138
|
-
adds = builder.instance_variable_get(:@adds)
|
139
|
-
circuit, _ = Builder::Finalizer.(adds)
|
140
|
-
|
141
|
-
Cct(circuit)
|
142
|
-
end
|
143
|
-
|
144
|
-
private
|
145
|
-
|
146
|
-
def self.Seq(sequence)
|
147
|
-
content =
|
148
|
-
sequence.collect do |(magnetic_to, task, plus_poles)|
|
149
|
-
pluses = plus_poles.collect { |plus_pole| PlusPole(plus_pole) }
|
150
|
-
|
151
|
-
%{#{magnetic_to.inspect} ==> #{Activity::Introspect.inspect_with_matcher(task)}
|
152
|
-
#{pluses.empty? ? " []" : pluses.join("\n")}}
|
153
|
-
end.join("\n")
|
154
|
-
|
155
|
-
"\n#{content}\n".gsub(/\d\d+/, "").gsub(/0x\w+/, "0x")
|
156
|
-
end
|
157
|
-
|
158
|
-
def self.PlusPole(plus_pole)
|
159
|
-
signal = plus_pole.signal.to_s.sub("Trailblazer::Activity::", "")
|
160
|
-
semantic = plus_pole.send(:output).semantic
|
161
|
-
" (#{semantic})/#{signal} ==> #{plus_pole.color.inspect}"
|
162
|
-
end
|
163
|
-
|
164
|
-
|
165
|
-
end
|
166
|
-
end
|
167
71
|
end
|