flor 1.6.2 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3016e8a2b0cf63ad1ccb0aa5a057bee3c4c99b6fd8889e5f4d5c9b8d84319295
4
- data.tar.gz: 9bf212da214adefa0f413277d74f13cfc8b8c3585962378d4279f45324cff2d7
3
+ metadata.gz: 726f12169dd650e862f4fdcf7f08da2e08f9a06ccf9f9125b2ad0340b4003b1f
4
+ data.tar.gz: 4864b67e47ee79e8a9b220e2465d23343e554102fd8a8fbdac6dad16eef9327c
5
5
  SHA512:
6
- metadata.gz: f17775b3282df1f8dfe02660422c14fad2c30815d80a1d242010d44715fad171543bd239371c43a3dcbdb2f9781eba2f3853a3dab0aa441e7cb0422cbdf1f06a
7
- data.tar.gz: 74d3fec7573d8a1c7b80a5cd5c100516a71b2903f51635d7b22a4b644e3865528eea7e38a1c75d0ec4df1e45b88e8b404edae47f54c3697c886e06d502ae388f
6
+ metadata.gz: 82a526fd4cd0c6185e3778e4b1421c6f120fa3b0a3c3591a54fb7ddb2ddae7943302409a5b1fe1bec118882ebaf125cdd6b35895f442d58b32068c80e17497b4
7
+ data.tar.gz: 80ab4a60ca328565ce463459ee610face1f9d513da541392c1d6c7b8bf0906c9271120dd1dbd94ea66589eda8c3112233f817d1ef6a38eb931bece7eda1cac7a
data/CHANGELOG.md CHANGED
@@ -2,7 +2,21 @@
2
2
  # CHANGELOG.md
3
3
 
4
4
 
5
- ## flor 1.6.2 released 2012-12-03
5
+ ## flor 1.6.4 released 2025-09-18
6
+
7
+ * Introduce `del` and `delf` to delete vars and fields
8
+ * Fix cursor/move vs symbol target
9
+
10
+
11
+ ## flor 1.6.3 released 2025-05-29
12
+
13
+ * Stop Scheduler#notify swallowing errors, gh-43
14
+ * Rework max_execution_count conf and use, gh-41
15
+ * Introduce Flor.pp(o, opts={}) and Flor.pp_to_s
16
+ * Set skip_transaction: true when reimporting ptrs
17
+
18
+
19
+ ## flor 1.6.2 released 2023-12-03
6
20
 
7
21
  * Prevent djan failing on negative indent for hash keys
8
22
 
data/CREDITS.md CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  ## Contributors
5
5
 
6
+ * pscholze - https://github.com/pscholze
6
7
  * Olle Jonsson - https://github.com/olleolleolle
7
8
  * Ryan Scott - https://github.com/Subtletree
8
9
  * Jeffrey Hicks - https://github.com/jrhicks
data/LICENSE.txt CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- Copyright (c) 2015-2023, John Mettraux, jmettraux+flor@gmail.com
2
+ Copyright (c) 2015-2025, John Mettraux, jmettraux+flor@gmail.com
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -6,8 +6,10 @@
6
6
 
7
7
  Flor is a "Ruby workflow engine", if that makes any sense.
8
8
 
9
+ <!--
9
10
  * [floraison mailing list](https://groups.google.com/forum/#!forum/floraison)
10
11
  * [twitter.com/@flor_workflow](https://twitter.com/flor_workflow)
12
+ -->
11
13
 
12
14
 
13
15
  ## use
@@ -36,7 +38,7 @@ Using flor in your Ruby project requires you to clearly separate business proces
36
38
 
37
39
  ## quickstart
38
40
 
39
- This quickstart sets up a flor unit tied to a SQLite database, resets the databse, binds two taskers and then launches a flow execution involving the two taskers. Finally, it prints out the resulting workitem as the execution has just terminated.
41
+ This quickstart sets up a flor unit tied to a SQLite database, resets the database, binds two taskers and then launches a flow execution involving the two taskers. Finally, it prints out the resulting workitem as the execution has just terminated.
40
42
 
41
43
  ```ruby
42
44
  require 'flor/unit'
@@ -94,7 +96,7 @@ p r['payload']['log']
94
96
 
95
97
  This quickstart is at [doc/quickstart0/](doc/quickstart0/), it's a minimal, one-file Ruby quickstart.
96
98
 
97
- There is also [doc/quickstart1/](doc/quickstart1/), a more complex example, that shows a flor setup, where taskers and flows are layed out in a flor directory tree.
99
+ There is also [doc/quickstart1/](doc/quickstart1/), a more complex example, that shows a flor setup, where taskers and flows are laid out in a flor directory tree.
98
100
 
99
101
 
100
102
  ## documentation
@@ -114,6 +116,8 @@ See [doc/](doc/).
114
116
  * [floraison/flack](https://github.com/floraison/flack) - a flor wrapping [Rack](https://github.com/rack/rack) app
115
117
  * [floraison/fugit](https://github.com/floraison/fugit) - a time library for flor and [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler)
116
118
  * [floraison/raabro](https://github.com/floraison/raabro) - the PEG library flor uses for its parsing needs
119
+ * [kiebor81/flor-language-service](https://github.com/kiebor81/flor-language-service) - a Visual Studio Code language service for the Flor language
120
+ * [flor.vim](https://github.com/floraison/flor/blob/master/misc/flor.vim) - a Vim syntax file for flor
117
121
 
118
122
 
119
123
  ## blog posts and presentations
@@ -138,10 +142,13 @@ There are various other Ruby and Ruby on Rails projects about workflows and busi
138
142
  * [Petri Flow](https://github.com/hooopo/petri_flow) - "Petri Net Workflow Engine for Ruby" (Rails)
139
143
  * [Pallets](https://github.com/linkyndy/pallets) - "Simple and reliable workflow engine, written in Ruby"
140
144
  * [Gush](https://github.com/chaps-io/gush) - "Fast and distributed workflow runner using ActiveJob and Redis"
145
+ * [Rukawa](https://github.com/joker1007/rukawa) - Hyper simple workflow engine powered by concurrent-ruby
146
+ * [ChronoForge](https://github.com/radioactive-labs/chrono_forge) - durable workflow engine for Ruby on Rails that provides reliable state management, error recovery, and workflow orchestration through ActiveJob
147
+ * [StepperMotor](https://github.com/stepper-motor/stepper_motor) - Effortless step workflows for Rails
141
148
 
142
149
  There is a [workflow engine](https://ruby.libhunt.com/categories/5786-workflow-engine) category on [Awesome Ruby](https://ruby.libhunt.com/).
143
150
 
144
- If you want your engine/library to be added in this list, don't hesitate to ask me on [Gitter](https://gitter.im/floraison/flor) or via a pull request.
151
+ If you want your engine/library to be added in this list, don't hesitate to ask me on via an [issue](https://github.com/floraison/flor/issues) or a pull request.
145
152
 
146
153
  It's not limited to Ruby, but there is a wider list at [meirwah/awesome-workflow-engines](https://github.com/meirwah/awesome-workflow-engines).
147
154
 
data/flor.gemspec CHANGED
@@ -40,7 +40,7 @@ A Ruby workflow engine (ruote next generation)
40
40
  #s.add_runtime_dependency 'rufus-lru', '~> 1.1'
41
41
  s.add_runtime_dependency 'munemo', '~> 1.0' # >= 1.0 and < 2
42
42
  s.add_runtime_dependency 'raabro', '~> 1.1' # >= 1.1 and < 2
43
- s.add_runtime_dependency 'fugit', '~> 1.2' # >= 1.2 and < 2
43
+ s.add_runtime_dependency 'fugit', '~> 1.10', '>= 1.11.1' # >= 1.2 and < 2
44
44
  s.add_runtime_dependency 'dense', '~> 1.1' # >= 1.1 and < 2
45
45
 
46
46
  s.add_runtime_dependency 'sequel', '~> 5.0' # >= 5.0 and < 6
data/lib/flor/colours.rb CHANGED
@@ -53,78 +53,78 @@ module Flor
53
53
  @colours = Colours.new
54
54
  @no_colours = NoColours.new
55
55
 
56
- def self.no_colours
56
+ class << self
57
57
 
58
- @no_colours
59
- end
58
+ def no_colours
60
59
 
61
- def self.colours(opts={})
60
+ @no_colours
61
+ end
62
62
 
63
- #opts =
64
- # case opts
65
- # when Hash then opts
66
- # when Colours, NoColours then { color: opts }
67
- # else { out: opts }
68
- # end
63
+ def colours(opts={})
69
64
 
70
- c = nil;
71
- [ :color, :colour, :colors, :colours ].each do |k|
72
- if opts.has_key?(k); c = opts[k]; break; end
73
- end
65
+ #opts =
66
+ # case opts
67
+ # when Hash then opts
68
+ # when Colours, NoColours then { color: opts }
69
+ # else { out: opts }
70
+ # end
74
71
 
75
- return @colours if c == true
76
- return @no_colours if c == false
72
+ c = nil;
73
+ [ :color, :colour, :colors, :colours ].each do |k|
74
+ if opts.has_key?(k); c = opts[k]; break; end
75
+ end
77
76
 
78
- o = opts[:out] || $stdout
77
+ return @colours if c == true
78
+ return @no_colours if c == false
79
79
 
80
- return @colours if (
81
- (o.respond_to?(:log_colours?) ? o.log_colours? : o.tty?) ||
82
- ($0[-6..-1] == '/rspec' &&
83
- (ARGV.include?('--tty') || ARGV.include?('--color'))))
80
+ o = opts[:out] || $stdout
84
81
 
85
- @no_colours
86
- end
82
+ return @colours if (
83
+ (o.respond_to?(:log_colours?) ? o.log_colours? : o.tty?) ||
84
+ ($0[-6..-1] == '/rspec' &&
85
+ (ARGV.include?('--tty') || ARGV.include?('--color'))))
87
86
 
88
- def self.decolour(s)
87
+ @no_colours
88
+ end
89
89
 
90
- s.gsub(/\x1b\[\d+(;\d+)?m/, '')
91
- end
90
+ def decolour(s)
92
91
 
93
- def self.no_colour_length(s)
92
+ s.gsub(/\x1b\[\d+(;\d+)?m/, '')
93
+ end
94
94
 
95
- decolour(s).length
96
- end
95
+ def no_colour_length(s)
97
96
 
98
- def self.truncate_string(s, maxlen, post='...')
97
+ decolour(s).length
98
+ end
99
99
 
100
- ncl = no_colour_length(s)
101
- r = StringIO.new
102
- l = 0
100
+ def truncate_string(s, maxlen, post='...')
103
101
 
104
- s.scan(/(\x1b\[\d+(?:;\d+)?m|[^\x1b]+)/) do |ss, _|
105
- if ss[0, 1] == ""
106
- r << ss
107
- else
102
+ ncl = no_colour_length(s)
103
+ r = StringIO.new
104
+ l = 0
105
+
106
+ s.scan(/(\x1b\[\d+(?:;\d+)?m|[^\x1b]+)/) do |ss, _|
107
+ if ss[0, 1] == ""
108
+ r << ss
109
+ else
108
110
  #p({ r: r.string, l: l, ssl: ss.length, maxlen: maxlen, reml: maxlen - l })
109
- ss = ss[0, maxlen - l]
110
- r << ss
111
- l += ss.length
112
- break if l >= maxlen
111
+ ss = ss[0, maxlen - l]
112
+ r << ss
113
+ l += ss.length
114
+ break if l >= maxlen
115
+ end
113
116
  end
114
- end
115
117
 
116
- return r.string if l < maxlen
117
-
118
- if post.is_a?(String)
119
- r << post
120
- elsif post.is_a?(Proc)
121
- r << post.call(ncl, maxlen, s)
122
- end
118
+ return r.string if l < maxlen
123
119
 
124
- r.string
125
- end
120
+ if post.is_a?(String)
121
+ r << post
122
+ elsif post.is_a?(Proc)
123
+ r << post.call(ncl, maxlen, s)
124
+ end
126
125
 
127
- class << self
126
+ r.string
127
+ end
128
128
 
129
129
  alias decolor decolour
130
130
 
data/lib/flor/conf.rb CHANGED
@@ -30,8 +30,8 @@ module Flor
30
30
  # reload/resync with db after how much time? (defaults to 60 (seconds))
31
31
  # minimizes communication with db in idle periods
32
32
  #
33
- # * :sch_max_executors
34
- # How many executor thread at most? (defaults to 7, 1 is OK in certain
33
+ # * :sch_max_executors or :sch_max_executor_count
34
+ # How many executor threads at most? (defaults to 7, 1 is OK in certain
35
35
  # environments)
36
36
  #
37
37
  # * :exe_max_messages
@@ -101,7 +101,7 @@ module Flor
101
101
  c.merge!(interpret_env)
102
102
  end
103
103
 
104
- c.merge!(over_conf)
104
+ c.merge!(Flor.to_string_keyed_hash(over_conf))
105
105
  end
106
106
 
107
107
  def get_class(conf, key)
@@ -156,7 +156,7 @@ module Flor
156
156
  end
157
157
  #
158
158
  # vars: variables
159
- # vdomain: variable domain (used in conjuction with the loader)
159
+ # vdomain: variable domain (used in conjunction with the loader)
160
160
  # cnid: closure nid
161
161
  # dbg: used to debug messages (useful @node['dbg'] when 'receive')
162
162
 
@@ -737,23 +737,28 @@ class Flor::Procedure < Flor::Node
737
737
  node = lookup_var_node(@node, mode, path)
738
738
  node = lookup_var_node(@node, 'l', path) if node.nil? && mode == ''
739
739
 
740
- return Dense.set(node['vars'], path, v) if node
740
+ if node
741
+ return Dense.unset(node['vars'], path) if v == :UNSET
742
+ return Dense.set(node['vars'], path, v)
743
+ end
741
744
 
742
745
  rescue IndexError
743
746
  end
744
747
 
745
748
  fail IndexError.new(
746
- "couldn't set var #{Flor.path_to_s([ "#{mode}v" ] + path)}")
749
+ "couldn't #{v == :UNSET ? 'un' : ''}set var " +
750
+ "#{Flor.path_to_s([ "#{mode}v" ] + path)}")
747
751
  end
748
752
 
749
753
  def set_field(path, v)
750
754
 
755
+ return Dense.unset(payload.copy, path) if v == :UNSET
751
756
  Dense.set(payload.copy, path, v)
752
757
 
753
758
  rescue IndexError
754
759
 
755
760
  fail IndexError.new(
756
- "couldn't set field #{Flor.path_to_s(path)}")
761
+ "couldn't #{v == :UNSET ? 'un' : ''}set field #{Flor.path_to_s(path)}")
757
762
  end
758
763
 
759
764
  def set_value(path, value)
@@ -775,6 +780,11 @@ class Flor::Procedure < Flor::Node
775
780
  end
776
781
  end
777
782
 
783
+ def unset_value(path)
784
+
785
+ set_value(path, :UNSET)
786
+ end
787
+
778
788
  def splat_value(paths, value)
779
789
 
780
790
  val = value.dup
@@ -872,7 +882,7 @@ class Flor::Procedure < Flor::Node
872
882
  end
873
883
 
874
884
  # Called by the executor, in turns call cancel and cancel_when_ methods
875
- # which may be overriden.
885
+ # which may be overridden.
876
886
  #
877
887
  def do_cancel
878
888
 
@@ -908,7 +918,7 @@ class Flor::Procedure < Flor::Node
908
918
  end
909
919
 
910
920
  # Called by the executor, in turns call kill and kill_when_ methods
911
- # which may be overriden.
921
+ # which may be overridden.
912
922
  #
913
923
  def do_kill
914
924
 
@@ -941,7 +951,7 @@ class Flor::Procedure < Flor::Node
941
951
  [] # no effect
942
952
  end
943
953
 
944
- # The core cancel work, is overriden by some procedure implementations.
954
+ # The core cancel work, is overridden by some procedure implementations.
945
955
  #
946
956
  def cancel
947
957
 
@@ -20,12 +20,12 @@ module Flor
20
20
  @archive = nil
21
21
  end
22
22
 
23
- def notify(executor, msg)
23
+ def notify(executor, message)
24
24
 
25
- return [] if msg['consumed']
25
+ return [] if message['consumed']
26
26
 
27
- @logger.notify(executor, msg)
28
- @journal << msg
27
+ @logger.notify(executor, message)
28
+ @journal << message
29
29
 
30
30
  []
31
31
  end
data/lib/flor/core.rb CHANGED
@@ -2,80 +2,93 @@
2
2
 
3
3
  module Flor
4
4
 
5
- def self.generate_exid(domain, unit)
5
+ class << self
6
6
 
7
- @exid_counter ||= 0
8
- @exid_mutex ||= Mutex.new
7
+ def generate_exid(domain, unit)
9
8
 
10
- t = Time.now.utc
9
+ @exid_counter ||= 0
10
+ @exid_mutex ||= Mutex.new
11
11
 
12
- sus =
13
- @exid_mutex.synchronize do
12
+ t = Time.now.utc
14
13
 
15
- sus = t.sec * 100000000 + t.usec * 100 + @exid_counter
14
+ sus =
15
+ @exid_mutex.synchronize do
16
16
 
17
- @exid_counter = @exid_counter + 1
18
- @exid_counter = 0 if @exid_counter > 99
17
+ sus = t.sec * 100000000 + t.usec * 100 + @exid_counter
19
18
 
20
- Munemo.to_s(sus)
21
- end
19
+ @exid_counter = @exid_counter + 1
20
+ @exid_counter = 0 if @exid_counter > 99
22
21
 
23
- t = t.strftime('%Y%m%d.%H%M')
22
+ Munemo.to_s(sus)
23
+ end
24
24
 
25
- "#{domain}-#{unit}-#{t}.#{sus}"
26
- end
25
+ t = t.strftime('%Y%m%d.%H%M')
27
26
 
28
- def self.make_launch_msg(exid, tree, opts)
27
+ "#{domain}-#{unit}-#{t}.#{sus}"
28
+ end
29
29
 
30
- t =
31
- tree.is_a?(String) ?
32
- Flor.parse(tree, opts[:fname] || opts[:path], opts) :
33
- tree
30
+ def make_launch_msg(exid, tree, opts)
34
31
 
35
- unless t
32
+ t =
33
+ tree.is_a?(String) ?
34
+ Flor.parse(tree, opts[:fname] || opts[:path], opts) :
35
+ tree
36
36
 
37
- #h = opts.merge(prune: false, rewrite: false, debug: 0)
38
- #Raabro.pp(Flor.parse(tree, h[:fname], h))
39
- # TODO re-parse and indicate what went wrong...
37
+ unless t
38
+
39
+ #h = opts.merge(prune: false, rewrite: false, debug: 0)
40
+ #Raabro.pp(Flor.parse(tree, h[:fname], h))
41
+ # TODO re-parse and indicate what went wrong...
42
+
43
+ fail ArgumentError.new(
44
+ "flow parsing failed: " + tree.inspect[0, 35] + '...')
45
+ end
46
+
47
+ pl = opts[:payload] || opts[:fields] || {}
48
+ vs = opts[:variables] || opts[:vars] || {}
40
49
 
41
50
  fail ArgumentError.new(
42
- "flow parsing failed: " + tree.inspect[0, 35] + '...')
43
- end
51
+ "given launch payload should be a Hash, but it's a #{pl.class}"
52
+ ) unless pl.is_a?(Hash)
53
+ fail ArgumentError.new(
54
+ "given launch variables should come in a Hash, but it's a #{vs.class}"
55
+ ) unless vs.is_a?(Hash)
44
56
 
45
- pl = opts[:payload] || opts[:fields] || {}
46
- vs = opts[:variables] || opts[:vars] || {}
57
+ msg = {
58
+ 'point' => 'execute',
59
+ 'exid' => exid,
60
+ 'nid' => '0',
61
+ 'tree' => t,
62
+ 'payload' => pl,
63
+ 'vars' => vs }
47
64
 
48
- fail ArgumentError.new(
49
- "given launch payload should be a Hash, but it's a #{pl.class}"
50
- ) unless pl.is_a?(Hash)
51
- fail ArgumentError.new(
52
- "given launch variables should come in a Hash, but it's a #{vs.class}"
53
- ) unless vs.is_a?(Hash)
65
+ msg['vdomain'] = opts[:vdomain] \
66
+ if opts.has_key?(:vdomain)
54
67
 
55
- msg = {
56
- 'point' => 'execute',
57
- 'exid' => exid,
58
- 'nid' => '0',
59
- 'tree' => t,
60
- 'payload' => pl,
61
- 'vars' => vs }
68
+ msg
69
+ end
62
70
 
63
- msg['vdomain'] = opts[:vdomain] \
64
- if opts.has_key?(:vdomain)
71
+ def load_procedures(dir)
65
72
 
66
- msg
67
- end
73
+ dirpath =
74
+ if dir.match(/\A[.\/]/)
75
+ File.join(dir, '*.rb')
76
+ else
77
+ File.join(File.dirname(__FILE__), dir, '*.rb')
78
+ end
68
79
 
69
- def self.load_procedures(dir)
80
+ Dir[dirpath].sort.each { |path| require(path) }
81
+ end
70
82
 
71
- dirpath =
72
- if dir.match(/\A[.\/]/)
73
- File.join(dir, '*.rb')
74
- else
75
- File.join(File.dirname(__FILE__), dir, '*.rb')
76
- end
83
+ def pp(o, opts={})
77
84
 
78
- Dir[dirpath].sort.each { |path| require(path) }
85
+ puts Flor.to_djan(o, { indent: 2, width: true }.merge(opts))
86
+ end
87
+
88
+ def pp_to_s(o, opts={})
89
+
90
+ Flor.to_djan(o, { indent: 2, width: true }.merge(opts))
91
+ end
79
92
  end
80
93
  end
81
94
 
data/lib/flor/parser.rb CHANGED
@@ -697,42 +697,45 @@ fail "don't know how to invert #{operation.inspect}" # FIXME
697
697
  alias rewrite_panode rewrite_flor
698
698
  end # module Parser
699
699
 
700
- def self.unescape_u(cs)
700
+ class << self
701
701
 
702
- s = ''; 4.times { s << cs.next }
702
+ def unescape_u(cs)
703
703
 
704
- [ s.to_i(16) ].pack('U*')
705
- end
704
+ s = ''; 4.times { s << cs.next }
705
+
706
+ [ s.to_i(16) ].pack('U*')
707
+ end
706
708
 
707
- def self.unescape(s)
709
+ def unescape(s)
708
710
 
709
- sio = StringIO.new
711
+ sio = StringIO.new
710
712
 
711
- cs = s.each_char
713
+ cs = s.each_char
712
714
 
713
- loop do
715
+ loop do
714
716
 
715
- c = cs.next
717
+ c = cs.next
716
718
 
717
- break unless c
719
+ break unless c
718
720
 
719
- if c == '\\'
720
- case cn = cs.next
721
- when 'u' then sio.print(unescape_u(cs))
722
- when '\\', '"', '\'' then sio.print(cn)
723
- when 'b' then sio.print("\b")
724
- when 'f' then sio.print("\f")
725
- when 'n' then sio.print("\n")
726
- when 'r' then sio.print("\r")
727
- when 't' then sio.print("\t")
728
- else sio.print("\\#{cn}")
721
+ if c == '\\'
722
+ case cn = cs.next
723
+ when 'u' then sio.print(unescape_u(cs))
724
+ when '\\', '"', '\'' then sio.print(cn)
725
+ when 'b' then sio.print("\b")
726
+ when 'f' then sio.print("\f")
727
+ when 'n' then sio.print("\n")
728
+ when 'r' then sio.print("\r")
729
+ when 't' then sio.print("\t")
730
+ else sio.print("\\#{cn}")
731
+ end
732
+ else
733
+ sio.print(c)
729
734
  end
730
- else
731
- sio.print(c)
732
735
  end
733
- end
734
736
 
735
- sio.string
737
+ sio.string
738
+ end
736
739
  end
737
740
  end
738
741
 
@@ -11,7 +11,7 @@ class Flor::Pro::Andor < Flor::Procedure
11
11
  # and
12
12
  # false
13
13
  # true
14
- # # => evalutes to false
14
+ # # => evaluates to false
15
15
  # ```
16
16
  #
17
17
  # ```
@@ -13,7 +13,7 @@ class Flor::Pro::Apply < Flor::Procedure
13
13
  # apply sum 1 2
14
14
  # ```
15
15
  #
16
- # It is usually used implicitely, as in
16
+ # It is usually used implicitly, as in
17
17
  # ```
18
18
  # sequence
19
19
  # define sum a b
@@ -7,8 +7,8 @@ class Flor::Pro::Break < Flor::Procedure
7
7
  # ```
8
8
  # until false
9
9
  # # do something
10
- # continue if f.x == 0
11
- # break if f.x == 1
10
+ # continue _ if f.x == 0
11
+ # break _ if f.x == 1
12
12
  # # do something more
13
13
  # ```
14
14
  #
@@ -50,7 +50,7 @@ class Flor::Pro::Break < Flor::Procedure
50
50
  #
51
51
  # While, until, loop and cursor.
52
52
 
53
- name 'break', 'continue'
53
+ names %w[ break continue ]
54
54
 
55
55
  def pre_execute
56
56
 
@@ -88,7 +88,7 @@ class Flor::Pro::Case < Flor::Procedure
88
88
  #
89
89
  # ### defaulting to f.ret
90
90
  #
91
- # When nothing is explicitely provided for consideration by "case", the
91
+ # When nothing is explicitly provided for consideration by "case", the
92
92
  # incoming `f.ret` is used.
93
93
  #
94
94
  # ```
@@ -191,6 +191,7 @@ class Flor::Pro::Cursor < Flor::Procedure
191
191
  find_string_target(to) ||
192
192
  find_name_target(to) ||
193
193
  find_att_target(to) ||
194
+ #find_att_value_target(to) ||
194
195
  fail(Flor::FlorError.new("move target #{to.inspect} not found", self))
195
196
  end
196
197
 
@@ -246,7 +247,16 @@ class Flor::Pro::Cursor < Flor::Procedure
246
247
  c[1].find { |cc|
247
248
  cc[0] == '_att' &&
248
249
  cc[1].is_a?(Array) &&
249
- cc[1][0][0, 2] == [ 'here', [] ] } } # FIXME hardcoded...
250
+ cc[1][0][0, 2] == [ to, [] ] } }
250
251
  end
252
+
253
+ #def find_att_value_target(to)
254
+ # tree[1]
255
+ # .index { |c|
256
+ # c[1].find { |cc|
257
+ # cc[1].length == 2 &&
258
+ # cc[1][0][0] != 'to' &&
259
+ # Flor.is_string_tree?(cc[1][1], to) } }
260
+ #end
251
261
  end
252
262