flor 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +9 -0
- data/CREDITS.md +21 -0
- data/LICENSE.txt +4 -1
- data/Makefile +4 -0
- data/README.md +8 -0
- data/flor.gemspec +10 -10
- data/lib/flor.rb +2 -2
- data/lib/flor/changes.rb +3 -3
- data/lib/flor/colours.rb +14 -8
- data/lib/flor/conf.rb +63 -58
- data/lib/flor/core.rb +4 -4
- data/lib/flor/core/executor.rb +65 -29
- data/lib/flor/core/node.rb +37 -20
- data/lib/flor/core/procedure.rb +182 -40
- data/lib/flor/core/texecutor.rb +125 -52
- data/lib/flor/djan.rb +111 -82
- data/lib/flor/dollar.rb +31 -30
- data/lib/flor/flor.rb +314 -237
- data/lib/flor/id.rb +7 -2
- data/lib/flor/log.rb +250 -245
- data/lib/flor/parser.rb +72 -38
- data/lib/flor/pcore/_arr.rb +10 -10
- data/lib/flor/pcore/_att.rb +49 -14
- data/lib/flor/pcore/_coll.rb +18 -0
- data/lib/flor/pcore/_obj.rb +23 -7
- data/lib/flor/pcore/_pat_.rb +1 -1
- data/lib/flor/pcore/_pat_guard.rb +8 -0
- data/lib/flor/pcore/_pat_obj.rb +3 -3
- data/lib/flor/pcore/_pat_or.rb +4 -0
- data/lib/flor/pcore/_pat_regex.rb +24 -0
- data/lib/flor/pcore/_skip.rb +4 -0
- data/lib/flor/pcore/_val.rb +0 -1
- data/lib/flor/pcore/all.rb +111 -0
- data/lib/flor/pcore/any.rb +83 -0
- data/lib/flor/pcore/arith.rb +35 -6
- data/lib/flor/pcore/break.rb +39 -1
- data/lib/flor/pcore/case.rb +82 -4
- data/lib/flor/pcore/cmp.rb +7 -7
- data/lib/flor/pcore/collect.rb +50 -0
- data/lib/flor/pcore/cond.rb +17 -3
- data/lib/flor/pcore/cursor.rb +8 -2
- data/lib/flor/pcore/detect.rb +45 -0
- data/lib/flor/pcore/each.rb +52 -0
- data/lib/flor/pcore/empty.rb +60 -0
- data/lib/flor/pcore/filter.rb +94 -0
- data/lib/flor/pcore/find.rb +67 -0
- data/lib/flor/pcore/for_each.rb +65 -0
- data/lib/flor/pcore/includes.rb +32 -0
- data/lib/flor/pcore/inject.rb +55 -0
- data/lib/flor/pcore/iterator.rb +151 -0
- data/lib/flor/pcore/keys.rb +60 -0
- data/lib/flor/pcore/length.rb +34 -7
- data/lib/flor/pcore/logo.rb +18 -0
- data/lib/flor/pcore/loop.rb +4 -0
- data/lib/flor/pcore/map.rb +77 -46
- data/lib/flor/pcore/match.rb +8 -2
- data/lib/flor/pcore/matchr.rb +4 -5
- data/lib/flor/pcore/move.rb +3 -3
- data/lib/flor/pcore/noeval.rb +13 -0
- data/lib/flor/pcore/not.rb +16 -0
- data/lib/flor/pcore/on.rb +172 -0
- data/lib/flor/pcore/on_cancel.rb +54 -0
- data/lib/flor/pcore/on_error.rb +68 -0
- data/lib/flor/pcore/rand.rb +2 -2
- data/lib/flor/pcore/range.rb +2 -1
- data/lib/flor/pcore/reduce.rb +124 -0
- data/lib/flor/pcore/reverse.rb +46 -0
- data/lib/flor/pcore/select.rb +72 -0
- data/lib/flor/pcore/set.rb +8 -0
- data/lib/flor/pcore/stall.rb +10 -0
- data/lib/flor/pcore/to_array.rb +61 -0
- data/lib/flor/pcore/until.rb +34 -0
- data/lib/flor/punit/cancel.rb +30 -5
- data/lib/flor/punit/ccollect.rb +11 -0
- data/lib/flor/punit/cmap.rb +10 -5
- data/lib/flor/punit/concurrence.rb +42 -51
- data/lib/flor/punit/cron.rb +33 -0
- data/lib/flor/punit/do_trap.rb +42 -0
- data/lib/flor/punit/every.rb +48 -13
- data/lib/flor/punit/graft.rb +3 -3
- data/lib/flor/punit/on_timeout.rb +38 -0
- data/lib/flor/punit/schedule.rb +69 -6
- data/lib/flor/punit/signal.rb +54 -0
- data/lib/flor/punit/sleep.rb +1 -1
- data/lib/flor/punit/task.rb +4 -1
- data/lib/flor/punit/trap.rb +188 -13
- data/lib/flor/tools/shell.rb +408 -62
- data/lib/flor/tools/shell_out.rb +31 -0
- data/lib/flor/unit.rb +1 -1
- data/lib/flor/unit/caller.rb +177 -0
- data/lib/flor/unit/executor.rb +1 -0
- data/lib/flor/unit/ganger.rb +15 -21
- data/lib/flor/unit/hook.rb +1 -1
- data/lib/flor/unit/hooker.rb +22 -10
- data/lib/flor/unit/loader.rb +22 -22
- data/lib/flor/unit/logger.rb +63 -36
- data/lib/flor/unit/models.rb +6 -1
- data/lib/flor/unit/models/execution.rb +12 -1
- data/lib/flor/unit/models/message.rb +7 -0
- data/lib/flor/unit/models/trap.rb +31 -17
- data/lib/flor/unit/scheduler.rb +18 -10
- data/lib/flor/unit/storage.rb +83 -23
- data/lib/flor/unit/waiter.rb +1 -2
- metadata +96 -52
- data/lib/flor/deep.rb +0 -144
- data/lib/flor/punit/on.rb +0 -57
- data/lib/flor/unit/runner.rb +0 -84
- data/match.md +0 -22
data/lib/flor/pcore/cmp.rb
CHANGED
@@ -13,9 +13,9 @@ class Flor::Pro::Cmp < Flor::Procedure
|
|
13
13
|
payload['ret'] =
|
14
14
|
if @node['rets'].size > 1
|
15
15
|
case tree[0]
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
when '=', '==' then check_equal
|
17
|
+
when '<', '>' then check_lesser
|
18
|
+
else true
|
19
19
|
end
|
20
20
|
else
|
21
21
|
true
|
@@ -36,10 +36,10 @@ class Flor::Pro::Cmp < Flor::Procedure
|
|
36
36
|
a, b = @node['rets'][-2], @node['rets'][-1]
|
37
37
|
|
38
38
|
case tree[0]
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
when '<' then return false if a >= b
|
40
|
+
when '<=' then return false if a > b
|
41
|
+
when '>' then return false if a <= b
|
42
|
+
when '>=' then return false if a < b
|
43
43
|
end
|
44
44
|
|
45
45
|
true
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
require 'flor/pcore/iterator'
|
3
|
+
|
4
|
+
|
5
|
+
class Flor::Pro::Collect < Flor::Macro::Iterator
|
6
|
+
#
|
7
|
+
# Collect is a simplified version of [map](map.md).
|
8
|
+
#
|
9
|
+
# ```
|
10
|
+
# map [ 1, 2, 3 ]
|
11
|
+
# def x
|
12
|
+
# + x 3
|
13
|
+
# #
|
14
|
+
# # becomes
|
15
|
+
# #
|
16
|
+
# collect [ 1, 2, 3 ]
|
17
|
+
# + elt 3
|
18
|
+
# ```
|
19
|
+
# Collect accepts, instead of a function, a block, where `elt` contains
|
20
|
+
# the current element and `idx` the current index.
|
21
|
+
#
|
22
|
+
# ```
|
23
|
+
# collect [ 'a', 'b' ]
|
24
|
+
# [ idx, elt ]
|
25
|
+
# ```
|
26
|
+
#
|
27
|
+
# ## iterating blocks
|
28
|
+
#
|
29
|
+
# Iterating blocks are given 3 to 4 local variables.
|
30
|
+
#
|
31
|
+
# A block iterating over an array will receive `elt` (the current element
|
32
|
+
# of the iteration), `idx` (the zero-based index of the current element),
|
33
|
+
# and `len` (the length of the array).
|
34
|
+
#
|
35
|
+
# A block iterating over an object will receive `key` (the current string
|
36
|
+
# key), `val` (the current value), `idx` (the zero-based index of the
|
37
|
+
# current key/val), and `len` (the length of the object).
|
38
|
+
#
|
39
|
+
# ## see also
|
40
|
+
#
|
41
|
+
# Map.
|
42
|
+
|
43
|
+
name 'collect'
|
44
|
+
|
45
|
+
def rewrite_tree
|
46
|
+
|
47
|
+
rewrite_iterator_tree('map')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
data/lib/flor/pcore/cond.rb
CHANGED
@@ -19,11 +19,25 @@ class Flor::Pro::Cond < Flor::Procedure
|
|
19
19
|
# ```
|
20
20
|
# set a 11
|
21
21
|
# cond
|
22
|
-
# a < 4
|
23
|
-
# a < 7
|
24
|
-
# else
|
22
|
+
# a < 4 ; "less than four"
|
23
|
+
# a < 7 ; "less than seven"
|
24
|
+
# else ; "ten or bigger"
|
25
25
|
# ```
|
26
26
|
# will yield "ten or bigger".
|
27
|
+
#
|
28
|
+
# The semicolon is used to place condition and clause on the same line.
|
29
|
+
# A pipe can be used instead of a semicolon.
|
30
|
+
# ```
|
31
|
+
# set a 11
|
32
|
+
# cond
|
33
|
+
# a < 4 | "less than four"
|
34
|
+
# a < 7 | "less than seven"
|
35
|
+
# else | "ten or bigger"
|
36
|
+
# ```
|
37
|
+
#
|
38
|
+
# ## see also
|
39
|
+
#
|
40
|
+
# If, match.
|
27
41
|
|
28
42
|
name 'cond'
|
29
43
|
|
data/lib/flor/pcore/cursor.rb
CHANGED
@@ -43,6 +43,10 @@ class Flor::Pro::Cursor < Flor::Procedure
|
|
43
43
|
# do-that _ # got skipped
|
44
44
|
# do-that-other-thing _
|
45
45
|
# ```
|
46
|
+
#
|
47
|
+
# ## see also
|
48
|
+
#
|
49
|
+
# Break, continue, loop.
|
46
50
|
|
47
51
|
name 'cursor'
|
48
52
|
|
@@ -122,14 +126,16 @@ class Flor::Pro::Cursor < Flor::Procedure
|
|
122
126
|
|
123
127
|
to = @message['to']
|
124
128
|
|
125
|
-
fail
|
129
|
+
fail Flor::FlorError.new(
|
130
|
+
"move target #{to.inspect} is not a string", self
|
131
|
+
) unless to.is_a?(String)
|
126
132
|
|
127
133
|
find_tag_target(to) ||
|
128
134
|
find_string_arg_target(to) ||
|
129
135
|
find_string_target(to) ||
|
130
136
|
find_name_target(to) ||
|
131
137
|
find_att_target(to) ||
|
132
|
-
fail("move target #{to.inspect} not found")
|
138
|
+
fail(Flor::FlorError.new("move target #{to.inspect} not found", self))
|
133
139
|
end
|
134
140
|
|
135
141
|
def is_tag_tree?(t, tagname)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
require 'flor/pcore/iterator'
|
3
|
+
|
4
|
+
|
5
|
+
class Flor::Pro::Detect < Flor::Macro::Iterator
|
6
|
+
#
|
7
|
+
# Detect is a simplified version of [find](find.md).
|
8
|
+
#
|
9
|
+
# ```
|
10
|
+
# detect [ 1, 2, 3 ]
|
11
|
+
# (elt % 2) == 0
|
12
|
+
# # f.ret --> 2
|
13
|
+
# ```
|
14
|
+
#
|
15
|
+
# With objects (maps), it returns the first matching entry (pair).
|
16
|
+
# ```
|
17
|
+
# detect { a: 'A', b: 'B', c: 'C' }
|
18
|
+
# val == 'B'
|
19
|
+
# # f.ret --> [ 'b', 'B' ]
|
20
|
+
# ```
|
21
|
+
#
|
22
|
+
# ## iterating blocks
|
23
|
+
#
|
24
|
+
# Iterating blocks are given 3 to 4 local variables.
|
25
|
+
#
|
26
|
+
# A block iterating over an array will receive `elt` (the current element
|
27
|
+
# of the iteration), `idx` (the zero-based index of the current element),
|
28
|
+
# and `len` (the length of the array).
|
29
|
+
#
|
30
|
+
# A block iterating over an object will receive `key` (the current string
|
31
|
+
# key), `val` (the current value), `idx` (the zero-based index of the
|
32
|
+
# current key/val), and `len` (the length of the object).
|
33
|
+
#
|
34
|
+
# ## see also
|
35
|
+
#
|
36
|
+
# find.
|
37
|
+
|
38
|
+
name 'detect'
|
39
|
+
|
40
|
+
def rewrite_tree
|
41
|
+
|
42
|
+
rewrite_iterator_tree('find')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
require 'flor/pcore/iterator'
|
3
|
+
|
4
|
+
|
5
|
+
class Flor::Pro::Each < Flor::Macro::Iterator
|
6
|
+
#
|
7
|
+
# Each is a simplified version of [for-each](for_each.md).
|
8
|
+
#
|
9
|
+
# Calls a function for each element in the argument collection.
|
10
|
+
#
|
11
|
+
# When the "each" ends, `f.ret` is pointing back to the argument
|
12
|
+
# collection.
|
13
|
+
#
|
14
|
+
# ```
|
15
|
+
# set l []
|
16
|
+
# each [ 0 1 2 3 4 5 6 7 ]
|
17
|
+
# pushr l (2 * elt) if elt % 2 == 0
|
18
|
+
# ```
|
19
|
+
# the var `l` will yield `[ 0, 4, 8, 12 ]` after the `each`
|
20
|
+
# the field `ret` will yield `[ 0, 1, 2, 3, 4, 5, 6, 7 ]`.
|
21
|
+
#
|
22
|
+
# ```
|
23
|
+
# set l []
|
24
|
+
# each { a: 'A', b: 'B', c: 'C' }
|
25
|
+
# pushr l (+ key val idx)
|
26
|
+
# ```
|
27
|
+
# the var `l` will yield `[ 'aA0', 'bB1', 'cC2' ]` after the `each`
|
28
|
+
#
|
29
|
+
# ## iterating blocks
|
30
|
+
#
|
31
|
+
# Iterating blocks are given 3 to 4 local variables.
|
32
|
+
#
|
33
|
+
# A block iterating over an array will receive `elt` (the current element
|
34
|
+
# of the iteration), `idx` (the zero-based index of the current element),
|
35
|
+
# and `len` (the length of the array).
|
36
|
+
#
|
37
|
+
# A block iterating over an object will receive `key` (the current string
|
38
|
+
# key), `val` (the current value), `idx` (the zero-based index of the
|
39
|
+
# current key/val), and `len` (the length of the object).
|
40
|
+
#
|
41
|
+
# ## see also
|
42
|
+
#
|
43
|
+
# for-each.
|
44
|
+
|
45
|
+
name 'each'
|
46
|
+
|
47
|
+
def rewrite_tree
|
48
|
+
|
49
|
+
rewrite_iterator_tree('for-each')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
class Flor::Pro::Empty < Flor::Procedure
|
3
|
+
#
|
4
|
+
# Returns true if the given collection or string is empty.
|
5
|
+
#
|
6
|
+
# Returns true of the given argument is null, returns false for any
|
7
|
+
# other non-collection, non-string argument.
|
8
|
+
#
|
9
|
+
# ```
|
10
|
+
# empty? [] # --> true
|
11
|
+
# empty? {} # --> true
|
12
|
+
# empty? '' # --> true
|
13
|
+
# empty? null # --> true
|
14
|
+
#
|
15
|
+
# empty? [ 1, 2, 3 ] # --> false
|
16
|
+
# empty? { a: 'A' } # --> false
|
17
|
+
# empty? 0 # --> false
|
18
|
+
# empty? 'aaa' # --> false
|
19
|
+
# ```
|
20
|
+
#
|
21
|
+
# If the argument is not an array, an object, a string or null, an
|
22
|
+
# error is triggered.
|
23
|
+
#
|
24
|
+
# If there is no argument to the "empty?", the incoming payload['ret']
|
25
|
+
# is considered
|
26
|
+
#
|
27
|
+
# ```
|
28
|
+
# {}
|
29
|
+
# empty? _ # --> true
|
30
|
+
#
|
31
|
+
# [ 1, 2, 3 ]
|
32
|
+
# empty? _ # --> false
|
33
|
+
# ```
|
34
|
+
#
|
35
|
+
# ## see also
|
36
|
+
#
|
37
|
+
# any?
|
38
|
+
|
39
|
+
name 'empty?'
|
40
|
+
|
41
|
+
def pre_execute
|
42
|
+
|
43
|
+
unatt_unkeyed_children
|
44
|
+
end
|
45
|
+
|
46
|
+
def receive_last
|
47
|
+
|
48
|
+
ret =
|
49
|
+
case r = payload['ret']
|
50
|
+
when Array, Hash, String then r.empty?
|
51
|
+
when nil then true
|
52
|
+
else
|
53
|
+
fail Flor::FlorError.new(
|
54
|
+
'argument is not an array, an object, a string or null', self)
|
55
|
+
end
|
56
|
+
|
57
|
+
wrap_reply('ret' => ret)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,94 @@
|
|
1
|
+
|
2
|
+
require 'flor/pcore/iterator'
|
3
|
+
|
4
|
+
|
5
|
+
class Flor::Pro::Filter < Flor::Pro::Iterator
|
6
|
+
#
|
7
|
+
# Filters a collection
|
8
|
+
#
|
9
|
+
# Expects a function in its arguments and a collection to filter
|
10
|
+
# in its arguments or as the incoming "ret".
|
11
|
+
#
|
12
|
+
# Fails if the collection or the function is missing.
|
13
|
+
#
|
14
|
+
# ```
|
15
|
+
# filter [ 1, 2, 3, 4, 5 ]
|
16
|
+
# def x
|
17
|
+
# = (x % 2) 1
|
18
|
+
#
|
19
|
+
# # f.ret --> [ 1, 3, 5 ]
|
20
|
+
# ```
|
21
|
+
#
|
22
|
+
# ## with objects (hashes)
|
23
|
+
#
|
24
|
+
# ```
|
25
|
+
# filter { a: 'A', b: 'B', c: 'C', d: 'D' }
|
26
|
+
# def k v i
|
27
|
+
# #or (k == 'a') (v == 'C') (i == 3)
|
28
|
+
# k == 'a' or v == 'C' or i == 3
|
29
|
+
#
|
30
|
+
# # f.ret --> { 'a' => 'A', 'c' => 'C', 'd' => 'D' }
|
31
|
+
# ```
|
32
|
+
#
|
33
|
+
# ## filter-out
|
34
|
+
#
|
35
|
+
# Is the negative sibling of "filter".
|
36
|
+
#
|
37
|
+
# ```
|
38
|
+
# filter-out [ 1, 2, 3, 4, 5 ]
|
39
|
+
# def x
|
40
|
+
# = (x % 2) 0
|
41
|
+
#
|
42
|
+
# # f.ret --> [ 1, 3, 5 ]
|
43
|
+
# ```
|
44
|
+
#
|
45
|
+
# ## incoming ret
|
46
|
+
#
|
47
|
+
# When not given directly a collection, `filter` takes it from the
|
48
|
+
# incoming "ret"
|
49
|
+
#
|
50
|
+
# ```
|
51
|
+
# { a: 'A', b: 'B', c: 'C', d: 'D' }
|
52
|
+
# filter
|
53
|
+
# def k v i l # key, value, index, length
|
54
|
+
# i = (l - 1) or i = (l - 2)
|
55
|
+
# # f.ret --> { 'c' => 'C', 'd' => 'D' }
|
56
|
+
# ```
|
57
|
+
#
|
58
|
+
# ## iterating and functions
|
59
|
+
#
|
60
|
+
# Iterating functions accept 0 to 3 arguments when iterating over an
|
61
|
+
# array and 0 to 4 arguments when iterating over an object.
|
62
|
+
#
|
63
|
+
# Those arguments are `[ value, index, length ]` for arrays.
|
64
|
+
# They are `[ key, value, index, length ]` for objects.
|
65
|
+
#
|
66
|
+
# The corresponding `key`, `val`, `idx` and `len` variables are also
|
67
|
+
# set in the closure for the function call.
|
68
|
+
#
|
69
|
+
# ## see also
|
70
|
+
#
|
71
|
+
# map, select, and reject.
|
72
|
+
|
73
|
+
names %w[ filter filter-out ]
|
74
|
+
|
75
|
+
protected
|
76
|
+
|
77
|
+
def receive_iteration
|
78
|
+
|
79
|
+
@node['res'] << @node['col'][@node['idx']] \
|
80
|
+
if (
|
81
|
+
(heap == 'filter' && Flor.true?(payload['ret'])) ||
|
82
|
+
(heap == 'filter-out' && Flor.false?(payload['ret'])))
|
83
|
+
end
|
84
|
+
|
85
|
+
def iterator_result
|
86
|
+
|
87
|
+
if @node['ocol'].is_a?(Hash)
|
88
|
+
Hash[@node['res']]
|
89
|
+
else
|
90
|
+
@node['res']
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
require 'flor/pcore/iterator'
|
3
|
+
|
4
|
+
|
5
|
+
class Flor::Pro::Find < Flor::Pro::Iterator
|
6
|
+
#
|
7
|
+
# Finds the first matching element.
|
8
|
+
#
|
9
|
+
# ```
|
10
|
+
# find [ 1, 2, 3 ]
|
11
|
+
# def elt
|
12
|
+
# (elt % 2) == 0
|
13
|
+
# # f.ret --> 2
|
14
|
+
# ```
|
15
|
+
#
|
16
|
+
# With objects (maps), it returns the first matching entry (pair).
|
17
|
+
# ```
|
18
|
+
# find { a: 'A', b: 'B', c: 'C' }
|
19
|
+
# def key, val
|
20
|
+
# val == 'B'
|
21
|
+
# # f.ret --> [ 'b', 'B' ]
|
22
|
+
# ```
|
23
|
+
#
|
24
|
+
# ## iterating and functions
|
25
|
+
#
|
26
|
+
# Iterating functions accept 0 to 3 arguments when iterating over an
|
27
|
+
# array and 0 to 4 arguments when iterating over an object.
|
28
|
+
#
|
29
|
+
# Those arguments are `[ value, index, length ]` for arrays.
|
30
|
+
# They are `[ key, value, index, length ]` for objects.
|
31
|
+
#
|
32
|
+
# The corresponding `key`, `val`, `idx` and `len` variables are also
|
33
|
+
# set in the closure for the function call.
|
34
|
+
#
|
35
|
+
# ## see also
|
36
|
+
#
|
37
|
+
# Map and detect, any?.
|
38
|
+
|
39
|
+
name 'find'
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
def pre_iterator
|
44
|
+
|
45
|
+
# nothing to do
|
46
|
+
end
|
47
|
+
|
48
|
+
def receive_iteration
|
49
|
+
|
50
|
+
# nothing to do
|
51
|
+
end
|
52
|
+
|
53
|
+
def iterator_over?
|
54
|
+
|
55
|
+
super || (@node['idx'] > 0 && Flor.true?(payload['ret']))
|
56
|
+
end
|
57
|
+
|
58
|
+
def iterator_result
|
59
|
+
|
60
|
+
if Flor.true?(payload['ret'])
|
61
|
+
@node['col'][@node['idx'] - 1]
|
62
|
+
else
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|