gloo 6.0 → 6.1.0

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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +9 -3
  3. data/README.md +38 -7
  4. data/docs/application.md +164 -0
  5. data/docs/getting_started.md +112 -0
  6. data/docs/iterators.md +294 -0
  7. data/docs/language_objects.md +190 -0
  8. data/docs/language_scripting.md +62 -0
  9. data/docs/language_syntax.md +307 -0
  10. data/docs/objects.md +77 -0
  11. data/docs/operators.md +62 -0
  12. data/docs/plugins.md +54 -0
  13. data/docs/verbs.md +64 -0
  14. data/gloo.gemspec +5 -3
  15. data/lib/VERSION +1 -1
  16. data/lib/VERSION_NOTES +14 -0
  17. data/lib/gloo/app/platform.rb +29 -2
  18. data/lib/gloo/app/settings.rb +1 -1
  19. data/lib/gloo/core/gloo_system.rb +52 -1
  20. data/lib/gloo/docs/doc_data.rb +160 -0
  21. data/lib/gloo/docs/help_shell.rb +285 -0
  22. data/lib/gloo/docs/markdown_renderer.rb +39 -0
  23. data/lib/gloo/objs/basic/alias.rb +53 -0
  24. data/lib/gloo/objs/basic/boolean.rb +30 -0
  25. data/lib/gloo/objs/basic/container.rb +38 -0
  26. data/lib/gloo/objs/basic/decimal.rb +30 -0
  27. data/lib/gloo/objs/basic/integer.rb +58 -0
  28. data/lib/gloo/objs/basic/script.rb +31 -0
  29. data/lib/gloo/objs/basic/string.rb +51 -4
  30. data/lib/gloo/objs/basic/string_msgs.rb +20 -0
  31. data/lib/gloo/objs/basic/text.rb +51 -4
  32. data/lib/gloo/objs/basic/untyped.rb +21 -0
  33. data/lib/gloo/objs/ctrl/each.rb +63 -1
  34. data/lib/gloo/objs/ctrl/function.rb +69 -0
  35. data/lib/gloo/objs/ctrl/repeat.rb +41 -0
  36. data/lib/gloo/objs/dt/date.rb +43 -0
  37. data/lib/gloo/objs/dt/datetime.rb +50 -0
  38. data/lib/gloo/objs/dt/time.rb +43 -0
  39. data/lib/gloo/objs/str_utils/cipher.rb +59 -0
  40. data/lib/gloo/objs/str_utils/outline.rb +65 -1
  41. data/lib/gloo/objs/str_utils/password.rb +56 -0
  42. data/lib/gloo/objs/system/erb.rb +39 -0
  43. data/lib/gloo/objs/system/file_handle.rb +56 -0
  44. data/lib/gloo/objs/system/system.rb +29 -0
  45. data/lib/gloo/objs/web/http_get.rb +35 -0
  46. data/lib/gloo/objs/web/http_post.rb +33 -0
  47. data/lib/gloo/objs/web/json.rb +40 -0
  48. data/lib/gloo/objs/web/uri.rb +40 -0
  49. data/lib/gloo/shell/command_node.rb +39 -0
  50. data/lib/gloo/shell/context.rb +93 -0
  51. data/lib/gloo/shell/runner.rb +315 -0
  52. data/lib/gloo/verbs/break.rb +32 -0
  53. data/lib/gloo/verbs/check.rb +49 -0
  54. data/lib/gloo/verbs/cls.rb +18 -0
  55. data/lib/gloo/verbs/context.rb +47 -0
  56. data/lib/gloo/verbs/create.rb +42 -0
  57. data/lib/gloo/verbs/eval.rb +27 -0
  58. data/lib/gloo/verbs/execute.rb +27 -0
  59. data/lib/gloo/verbs/exists.rb +54 -2
  60. data/lib/gloo/verbs/files.rb +22 -0
  61. data/lib/gloo/verbs/help.rb +43 -178
  62. data/lib/gloo/verbs/if.rb +52 -0
  63. data/lib/gloo/verbs/invoke.rb +62 -0
  64. data/lib/gloo/verbs/list.rb +32 -0
  65. data/lib/gloo/verbs/load.rb +55 -2
  66. data/lib/gloo/verbs/log.rb +44 -0
  67. data/lib/gloo/verbs/move.rb +36 -1
  68. data/lib/gloo/verbs/put.rb +35 -0
  69. data/lib/gloo/verbs/quit.rb +19 -0
  70. data/lib/gloo/verbs/redirect.rb +52 -2
  71. data/lib/gloo/verbs/reload.rb +27 -0
  72. data/lib/gloo/verbs/run.rb +39 -0
  73. data/lib/gloo/verbs/save.rb +26 -0
  74. data/lib/gloo/verbs/show.rb +54 -0
  75. data/lib/gloo/verbs/tell.rb +32 -0
  76. data/lib/gloo/verbs/throw.rb +29 -0
  77. data/lib/gloo/verbs/unless.rb +50 -0
  78. data/lib/gloo/verbs/unload.rb +23 -0
  79. data/lib/gloo/verbs/version.rb +37 -3
  80. data/lib/gloo/verbs/wait.rb +26 -0
  81. metadata +28 -20
@@ -0,0 +1,285 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2026 Eric Crane. All rights reserved.
3
+ #
4
+ # The interactive help shell, entered by the `help`/`?` verb.
5
+ # Built on Gloo::Shell::Runner (see lib/gloo/shell/).
6
+ #
7
+ require_relative '../shell/runner'
8
+ require_relative 'markdown_renderer'
9
+
10
+ module Gloo
11
+ module Docs
12
+ class HelpShell < Gloo::Shell::Runner
13
+
14
+ PROMPT = 'help>'.freeze
15
+ NO_DOC_YET = 'No documentation available yet for'.freeze
16
+
17
+ VERB_NAMES = :verb_names
18
+ OBJECT_NAMES = :object_names
19
+ DOC_NAMES = :doc_names
20
+ LIBRARY_NAMES = :library_names
21
+ EXTENSION_NAMES = :extension_names
22
+
23
+ DOCS_DIR = File.expand_path( '../../../docs', __dir__ ).freeze
24
+ README_GLOB = 'README*'.freeze
25
+ NO_README_YET = 'No README found for library'.freeze
26
+
27
+ #
28
+ # Initialize the help shell for the given engine.
29
+ #
30
+ def initialize( engine )
31
+ super( engine, prompt: PROMPT, include_quit: true )
32
+ populate_context
33
+ build_commands
34
+ end
35
+
36
+ # ---------------------------------------------------------------------
37
+ # Root commands - lists (mirrors the old help v/o/s/e/l dispatch)
38
+ # ---------------------------------------------------------------------
39
+
40
+ #
41
+ # List all verbs.
42
+ #
43
+ def cmd_show_verbs( _obj, _context )
44
+ data = "\n"
45
+ data << " Verbs (shortcut, name)\n".blue
46
+ @engine.dictionary.get_verbs.sort_by( &:keyword ).each do |v|
47
+ cut = v.keyword_shortcut.ljust( 5, ' ' ).yellow
48
+ name = v.keyword.ljust( 20, ' ' ).white
49
+ data << " #{cut} #{name} \n"
50
+ end
51
+ @engine.log.show "#{data}\n"
52
+ end
53
+
54
+ #
55
+ # List all object types.
56
+ #
57
+ def cmd_show_objects( _obj, _context )
58
+ data = "\n"
59
+ data << " Objects \n".blue
60
+ @engine.dictionary.get_obj_types.sort_by( &:typename ).each do |o|
61
+ if o.short_typename != o.typename
62
+ short = "(#{o.short_typename})".yellow
63
+ name = "#{o.typename.white} #{short}"
64
+ else
65
+ name = o.typename.white
66
+ end
67
+ data << " #{name.ljust( 30, ' ' )}\n"
68
+ end
69
+ @engine.log.show "#{data}\n"
70
+ end
71
+
72
+ #
73
+ # Show application settings.
74
+ #
75
+ def cmd_show_settings( _obj, _context )
76
+ @engine.settings.show
77
+ end
78
+
79
+ #
80
+ # List loaded extensions.
81
+ #
82
+ def cmd_show_extensions( _obj, _context )
83
+ data = "\n"
84
+ data << " Extensions\n".blue
85
+ data << " Use `load ext {name}` to load a User Extension, \n" \
86
+ " then `object {name}` / `verb {name}` / `extension {name}` here to see what it adds. \n" \
87
+ " Only loaded extensions are listed below.\n\n".light_black
88
+ loaded = @engine.ext_manager.loaded_extensions
89
+ if loaded.empty?
90
+ data << " (none loaded)\n".light_black
91
+ else
92
+ loaded.sort.each do |name, _ext|
93
+ data << " #{name.white} \n"
94
+ end
95
+ end
96
+ @engine.log.show "#{data}\n"
97
+ end
98
+
99
+ #
100
+ # List loaded libraries.
101
+ #
102
+ def cmd_show_libraries( _obj, _context )
103
+ data = "\n"
104
+ data << " Libraries\n".blue
105
+ data << " Use `load lib {name}` to load a core library, \n" \
106
+ " then `object {name}` / `verb {name}` here to see what it adds. \n" \
107
+ " Only loaded libraries are listed below.\n\n".light_black
108
+ loaded = @engine.lib_manager.loaded_libraries
109
+ if loaded.empty?
110
+ data << " (none loaded)\n".light_black
111
+ else
112
+ loaded.sort.each do |name, _lib|
113
+ data << " #{name.white} \n"
114
+ end
115
+ end
116
+ @engine.log.show "#{data}\n"
117
+ end
118
+
119
+ #
120
+ # List all narrative doc pages (dev/gloo/docs/*.md).
121
+ #
122
+ def cmd_show_docs( _obj, _context )
123
+ data = "\n"
124
+ data << " Docs\n".blue
125
+ doc_page_names.each do |name|
126
+ data << " #{name.white}\n"
127
+ end
128
+ @engine.log.show "#{data}\n"
129
+ end
130
+
131
+ # ---------------------------------------------------------------------
132
+ # Detail commands - verb {name}, object {name}, doc {name},
133
+ # library {name}
134
+ # ---------------------------------------------------------------------
135
+
136
+ #
137
+ # Show detailed help for one verb.
138
+ #
139
+ def cmd_show_verb_detail( obj, _context )
140
+ verb_class = @engine.dictionary.find_verb( obj )
141
+ return @engine.log.show "#{NO_DOC_YET} '#{obj}'." unless verb_class.respond_to?( :doc_data )
142
+
143
+ page_markdown( Gloo::Docs::DocData.new( verb_class.doc_data ).render )
144
+ end
145
+
146
+ #
147
+ # Show detailed help for one object type.
148
+ #
149
+ def cmd_show_object_detail( obj, _context )
150
+ obj_class = @engine.dictionary.find_obj( obj )
151
+ return @engine.log.show "#{NO_DOC_YET} '#{obj}'." unless obj_class.respond_to?( :doc_data )
152
+
153
+ page_markdown( Gloo::Docs::DocData.new( obj_class.doc_data ).render )
154
+ end
155
+
156
+ #
157
+ # Show one narrative doc page (dev/gloo/docs/{name}.md).
158
+ #
159
+ def cmd_show_doc_detail( obj, _context )
160
+ path = File.join( DOCS_DIR, "#{obj}.md" )
161
+ return @engine.log.show "#{NO_DOC_YET} '#{obj}'." unless File.exist?( path )
162
+
163
+ page_markdown( File.read( path ) )
164
+ end
165
+
166
+ #
167
+ # Show the README for one loaded core library (from the root of
168
+ # its installed gem). Only loaded libraries are tab-completable
169
+ # here - see cmd_show_libraries.
170
+ #
171
+ def cmd_show_library_detail( obj, _context )
172
+ gem_name = @engine.lib_manager.loaded_libraries[ obj ]
173
+ return @engine.log.show "#{NO_DOC_YET} '#{obj}'." unless gem_name
174
+
175
+ readme_path = find_readme( gem_name )
176
+ return @engine.log.show "#{NO_README_YET} '#{obj}' (#{gem_name})." unless readme_path
177
+
178
+ page_markdown( File.read( readme_path ) )
179
+ end
180
+
181
+ #
182
+ # Show the README for one loaded user extension (from the root of
183
+ # its extension folder, e.g. ~/gloo/extensions/{name}). Only loaded
184
+ # extensions are tab-completable here - see cmd_show_extensions.
185
+ #
186
+ def cmd_show_extension_detail( obj, _context )
187
+ start_file = @engine.ext_manager.loaded_extensions[ obj ]
188
+ return @engine.log.show "#{NO_DOC_YET} '#{obj}'." unless start_file
189
+
190
+ readme_path = find_extension_readme( start_file )
191
+ return @engine.log.show "#{NO_README_YET} '#{obj}'." unless readme_path
192
+
193
+ page_markdown( File.read( readme_path ) )
194
+ end
195
+
196
+ # ---------------------------------------------------------------------
197
+ # Private
198
+ # ---------------------------------------------------------------------
199
+
200
+ private
201
+
202
+ #
203
+ # Colorize markdown and page it, bracketed with a '---' rule above
204
+ # and below so the content stands out from surrounding CLI output.
205
+ #
206
+ def page_markdown( md )
207
+ rule = '-' * @engine.platform.cols
208
+ bracketed = "#{rule}\n#{md.strip}\n#{rule}\n"
209
+ @engine.platform.page( Gloo::Docs::MarkdownRenderer.colorize( bracketed ) )
210
+ end
211
+
212
+ #
213
+ # Snapshot the verb, object type, doc page, and loaded library
214
+ # names for tab-completion.
215
+ #
216
+ def populate_context
217
+ set_context( VERB_NAMES, @engine.dictionary.get_verbs.map( &:keyword ).sort )
218
+ set_context( OBJECT_NAMES, @engine.dictionary.get_obj_types.map( &:typename ).sort )
219
+ set_context( DOC_NAMES, doc_page_names )
220
+ set_context( LIBRARY_NAMES, @engine.lib_manager.loaded_libraries.keys.sort )
221
+ set_context( EXTENSION_NAMES, @engine.ext_manager.loaded_extensions.keys.sort )
222
+ end
223
+
224
+ #
225
+ # Find the README file at the root of an installed gem, if any.
226
+ #
227
+ def find_readme( gem_name )
228
+ spec = Gem::Specification.find_by_name( gem_name )
229
+ return Dir.glob( File.join( spec.gem_dir, README_GLOB ) ).first
230
+ rescue Gem::MissingSpecError
231
+ return nil
232
+ end
233
+
234
+ #
235
+ # Find the README file at the root of an extension's folder, given
236
+ # the full path to its {name}_ext.rb start file.
237
+ #
238
+ def find_extension_readme( start_file )
239
+ root = File.dirname( start_file )
240
+ return Dir.glob( File.join( root, README_GLOB ) ).first
241
+ end
242
+
243
+ #
244
+ # List the narrative doc page names (dev/gloo/docs/*.md, without extension).
245
+ #
246
+ def doc_page_names
247
+ return Dir.glob( File.join( DOCS_DIR, '*.md' ) ).map { |f| File.basename( f, '.md' ) }.sort
248
+ end
249
+
250
+ #
251
+ # Build the help shell's command tree.
252
+ #
253
+ def build_commands
254
+ add_command_node(
255
+ name: 'verbs', description: 'List all verbs', method: 'cmd_show_verbs' )
256
+ add_command_node(
257
+ name: 'objects', description: 'List all object types', method: 'cmd_show_objects' )
258
+ add_command_node(
259
+ name: 'settings', description: 'Show application settings', method: 'cmd_show_settings' )
260
+ add_command_node(
261
+ name: 'extensions', description: 'List loaded extensions', method: 'cmd_show_extensions' )
262
+ add_command_node(
263
+ name: 'libraries', description: 'List loaded libraries', method: 'cmd_show_libraries' )
264
+ add_command_node(
265
+ name: 'docs', description: 'List all narrative doc pages', method: 'cmd_show_docs' )
266
+ add_command_node(
267
+ name: 'verb', description: 'Show detailed help for a verb',
268
+ dynamic: true, source: VERB_NAMES, child_method: 'cmd_show_verb_detail' )
269
+ add_command_node(
270
+ name: 'object', description: 'Show detailed help for an object type',
271
+ dynamic: true, source: OBJECT_NAMES, child_method: 'cmd_show_object_detail' )
272
+ add_command_node(
273
+ name: 'doc', description: 'Show one narrative doc page',
274
+ dynamic: true, source: DOC_NAMES, child_method: 'cmd_show_doc_detail' )
275
+ add_command_node(
276
+ name: 'library', description: "Show a loaded library's README",
277
+ dynamic: true, source: LIBRARY_NAMES, child_method: 'cmd_show_library_detail' )
278
+ add_command_node(
279
+ name: 'extension', description: "Show a loaded extension's README",
280
+ dynamic: true, source: EXTENSION_NAMES, child_method: 'cmd_show_extension_detail' )
281
+ end
282
+
283
+ end
284
+ end
285
+ end
@@ -0,0 +1,39 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2026 Eric Crane. All rights reserved.
3
+ #
4
+ # Lightly colorize markdown for terminal display: headings and code
5
+ # fences get ANSI color, everything else passes through unchanged.
6
+ # Not a full markdown renderer - just enough that the raw
7
+ # `#`/```` ``` ```` syntax doesn't have to be read literally.
8
+ #
9
+ # Shared by the narrative doc pages (dev/gloo/docs/*.md) and the
10
+ # verb/object detail pages (Gloo::Docs::DocData#render), so both are
11
+ # paged through the same visual style.
12
+ #
13
+ module Gloo
14
+ module Docs
15
+ class MarkdownRenderer
16
+
17
+ #
18
+ # Colorize the given markdown text for terminal display.
19
+ def self.colorize( text )
20
+ in_code = false
21
+ lines = text.split( "\n" ).map do |line|
22
+ if line.start_with?( '```' )
23
+ in_code = !in_code
24
+ next line.light_black
25
+ end
26
+ next line.light_black if in_code
27
+ next line.sub( /^#\s*/, '' ).blue.bold if line.start_with?( '# ' )
28
+ next line.sub( /^##\s*/, '' ).cyan.bold if line.start_with?( '## ' )
29
+ next line.cyan if line.start_with?( '### ' ) || line.start_with?( '#### ' )
30
+ next line.light_black if line =~ /\A-{3,}\z/
31
+
32
+ line
33
+ end
34
+ return lines.join( "\n" )
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -73,6 +73,59 @@ module Gloo
73
73
  return ln.resolve
74
74
  end
75
75
 
76
+ # ---------------------------------------------------------------------
77
+ # Object Documentation
78
+ # ---------------------------------------------------------------------
79
+
80
+ #
81
+ # Get the object's documentation data.
82
+ #
83
+ def self.doc_data
84
+ {
85
+ :name => KEYWORD,
86
+ :shortcut => KEYWORD_SHORT,
87
+ :description => 'A pointer to another object. Normal ' \
88
+ 'path-name references will refer to the aliased object. To ' \
89
+ 'refer to the alias itself, add an * at the end of the ' \
90
+ 'path-name — needed, for example, to set the value of the ' \
91
+ 'alias. The value of the alias is merely the path-name of ' \
92
+ 'the referenced object. Well constructed aliases will ' \
93
+ 'redirect to the referenced object through any number of ' \
94
+ 'steps, and relative references will also work in an alias.',
95
+ :messages => [
96
+ 'resolve — Check to see if the object referenced exists. Sets it to true or false.'
97
+ ],
98
+ :notes => 'The alias also reflects (forwards) the messages of the object it points to.',
99
+ :examples => <<~EXAMPLES.strip
100
+ #
101
+ # Alias object.
102
+ #
103
+
104
+ a [can] :
105
+ s [string] : a string
106
+ i [integer] : 13
107
+ ln [alias] : a.s
108
+
109
+ on_load [script] :
110
+ show a.ln
111
+ show a.ln*
112
+ put 'a.i' into a.ln*
113
+ put 7 into a.ln
114
+ show a.ln
115
+ run a.add
116
+
117
+ #
118
+ # Example of creating an object using an alias.
119
+ #
120
+ add [script] :
121
+ put 'x' into a.ln*
122
+ create a.ln* as string
123
+ put 'test' into x
124
+ show a.ln
125
+ EXAMPLES
126
+ }
127
+ end
128
+
76
129
  end
77
130
  end
78
131
  end
@@ -115,6 +115,36 @@ module Gloo
115
115
  return false
116
116
  end
117
117
 
118
+ # ---------------------------------------------------------------------
119
+ # Object Documentation
120
+ # ---------------------------------------------------------------------
121
+
122
+ #
123
+ # Get the object's documentation data.
124
+ #
125
+ def self.doc_data
126
+ {
127
+ :name => KEYWORD,
128
+ :shortcut => KEYWORD_SHORT,
129
+ :description => 'A boolean value. Value will be either true or false.',
130
+ :messages => [
131
+ 'not — Set the boolean to the opposite of what it is now.',
132
+ 'true — Set the boolean to true.',
133
+ 'false — Set the boolean to false.'
134
+ ],
135
+ :examples => <<~EXAMPLES.strip
136
+ b [can] :
137
+ flag [boolean] : true
138
+ on_load [script] :
139
+ show b.flag
140
+ put false into b.flag
141
+ show b.flag
142
+ tell b.flag to not
143
+ show b.flag
144
+ EXAMPLES
145
+ }
146
+ end
147
+
118
148
  end
119
149
  end
120
150
  end
@@ -75,6 +75,44 @@ module Gloo
75
75
  @engine.heap.it.set_to val
76
76
  return val
77
77
  end
78
+
79
+ # ---------------------------------------------------------------------
80
+ # Object Documentation
81
+ # ---------------------------------------------------------------------
82
+
83
+ #
84
+ # Get the object's documentation data.
85
+ #
86
+ def self.doc_data
87
+ {
88
+ :name => KEYWORD,
89
+ :shortcut => KEYWORD_SHORT,
90
+ :description => 'A container of other objects. A container is ' \
91
+ 'similar to a folder in a file system. It can contain any ' \
92
+ 'number of objects including other containers. The ' \
93
+ 'container structure provides direct access to any object ' \
94
+ 'within it through the object.object.object path-name structure.',
95
+ :children => [
96
+ 'None by default — but any container can have any number of objects added to it, at runtime.'
97
+ ],
98
+ :messages => [
99
+ 'count — Count the number of children objects in the container. The result is put in it.',
100
+ 'delete_children — Delete all children objects from the container.',
101
+ 'show_key_value_table — Show a table with key (name) and values for all children in the container.',
102
+ 'child_exists ({name}) — Check to see if there is a child with the given name. A parameter is required. It will have a boolean.'
103
+ ],
104
+ :examples => <<~EXAMPLES.strip
105
+ can [can] :
106
+ data [can] :
107
+ 1 : one
108
+ 2 : two
109
+ 3 : three
110
+ on_load [script] :
111
+ tell can.data to show_key_value_table
112
+ EXAMPLES
113
+ }
114
+ end
115
+
78
116
  end
79
117
  end
80
118
  end
@@ -92,6 +92,36 @@ module Gloo
92
92
  @engine.heap.it.set_to formatted
93
93
  end
94
94
 
95
+ # ---------------------------------------------------------------------
96
+ # Object Documentation
97
+ # ---------------------------------------------------------------------
98
+
99
+ #
100
+ # Get the object's documentation data.
101
+ #
102
+ def self.doc_data
103
+ {
104
+ :name => KEYWORD,
105
+ :shortcut => KEYWORD_SHORT,
106
+ :description => 'A decimal (numeric) value.',
107
+ :messages => [
108
+ 'round ({precision}) — Round to the nearest whole value. If ' \
109
+ 'an optional parameter is included, round to the precision specified.',
110
+ 'format ({fmt}) — With no parameter, adds comma separators to the whole part (e.g. 1000.5 -> 1,000.5). With a parameter, uses it as a sprintf-style format string (e.g. \'%.2f\'). It will have the formatted string.'
111
+ ],
112
+ :examples => <<~EXAMPLES.strip
113
+ d [can] :
114
+ x [decimal] : 100
115
+ on_load [script] :
116
+ show d.x
117
+ put d.x / 3 into d.x
118
+ show d.x
119
+ tell d.x to round (1)
120
+ show d.x
121
+ EXAMPLES
122
+ }
123
+ end
124
+
95
125
  end
96
126
  end
97
127
  end
@@ -118,6 +118,64 @@ module Gloo
118
118
  @engine.heap.it.set_to formatted
119
119
  end
120
120
 
121
+ # ---------------------------------------------------------------------
122
+ # Object Documentation
123
+ # ---------------------------------------------------------------------
124
+
125
+ #
126
+ # Get the object's documentation data.
127
+ #
128
+ def self.doc_data
129
+ {
130
+ :name => KEYWORD,
131
+ :shortcut => KEYWORD_SHORT,
132
+ :description => 'An integer (numeric) value.',
133
+ :messages => [
134
+ 'inc — Increment the integer value by 1.',
135
+ 'dec — Decrement the integer value by 1.',
136
+ 'randomize ({max}) — Set the value of the integer to a random ' \
137
+ 'number. By default the range is 0..99 inclusive. Use an ' \
138
+ 'optional parameter to set the maximum of the range; the ' \
139
+ 'range always starts at 0. To model a 6-sided die, set the ' \
140
+ 'range to 6 and add 1 to the result.',
141
+ 'format ({fmt}) — With no parameter, adds comma separators (e.g. 1000 -> 1,000). With a parameter, uses it as a sprintf-style format string (e.g. \'%05d\'). It will have the formatted string.'
142
+ ],
143
+ :examples => <<~EXAMPLES.strip
144
+ #
145
+ # Integer object.
146
+ #
147
+
148
+ i [can] :
149
+
150
+ #
151
+ # The integer value.
152
+ #
153
+ x [integer] : 0
154
+
155
+ #
156
+ # Do some basic tests with it
157
+ #
158
+ on_load [script] :
159
+ show i.x
160
+ tell i.x to inc
161
+ show i.x
162
+ put i.x * 10 into i.x
163
+ show i.x
164
+
165
+ # Show a random number
166
+ tell ^.x to randomize
167
+ show 'Random number (up to 100 by default): ' + ^.x
168
+
169
+ tell ^.x to randomize(6)
170
+ tell ^.x to inc
171
+ show '6-sided dice: ' + ^.x
172
+
173
+ # An uninitialized integer.
174
+ y [integer] :
175
+ EXAMPLES
176
+ }
177
+ end
178
+
121
179
  end
122
180
  end
123
181
  end
@@ -94,6 +94,37 @@ module Gloo
94
94
  s.run
95
95
  end
96
96
 
97
+ # ---------------------------------------------------------------------
98
+ # Object Documentation
99
+ # ---------------------------------------------------------------------
100
+
101
+ #
102
+ # Get the object's documentation data.
103
+ #
104
+ def self.doc_data
105
+ {
106
+ :name => KEYWORD,
107
+ :shortcut => KEYWORD_SHORT,
108
+ :description => 'An executable script — a set of commands to be run.',
109
+ :messages => [
110
+ 'run — Run the script. The script can be run by telling the ' \
111
+ 'object to run, or via the run verb.'
112
+ ],
113
+ :examples => <<~EXAMPLES.strip
114
+ script [can] :
115
+ on_load [script] :
116
+ show "Showing multiple lines..."
117
+ show script.msg1
118
+ show script.msg2
119
+ show script.msg3
120
+ show "Done."
121
+ msg1 [string] : one
122
+ msg2 [string] : two
123
+ msg3 [string] : three
124
+ EXAMPLES
125
+ }
126
+ end
127
+
97
128
  end
98
129
  end
99
130
  end
@@ -44,10 +44,57 @@ module Gloo
44
44
  # Get a list of message names that this object receives.
45
45
  #
46
46
  def self.messages
47
- return super + %w[up down size starts_with? ends_with? substring? sub gsub
48
- count_lines count_words count_chars trim
49
- format_for_html encode64 decode64 escape unescape
50
- gen_alphanumeric gen_uuid gen_hex gen_base64]
47
+ return super + StringMsgs.messages
48
+ end
49
+
50
+ # ---------------------------------------------------------------------
51
+ # Object Documentation
52
+ # ---------------------------------------------------------------------
53
+
54
+ #
55
+ # Get the object's documentation data.
56
+ #
57
+ def self.doc_data
58
+ {
59
+ :name => KEYWORD,
60
+ :shortcut => KEYWORD_SHORT,
61
+ :description => 'A string value. For string interpolation, ' \
62
+ 'see the erb object type.',
63
+ :messages => [
64
+ 'up — Convert the string to uppercase. This message changes the value of the string.',
65
+ 'down — Convert the string to lowercase. This message changes the value of the string.',
66
+ 'size — Get the size of the string. It will have the string size.',
67
+ 'count_chars — Count the number of characters in the string. It will have the character count.',
68
+ 'count_words — Count the number of words in the string. It will have the word count.',
69
+ 'count_lines — Count the number of lines in the string. It will have the line count.',
70
+ 'starts_with? ({str}) — Check if the string starts with the given string. A parameter is required: the string to look for at the beginning of this string. It will have a boolean.',
71
+ 'ends_with? ({str}) — Check if the string ends with the given string. A parameter is required: the string to look for at the end of this string. It will have a boolean.',
72
+ 'substring? ({str}) — Check if the string includes the given sub-string. A parameter is required: the string to look for in this string. It will have a boolean.',
73
+ 'format_for_html — Format this string for HTML output. Tabs, spaces and returns are converted to HTML elements. The value of the string is changed.',
74
+ 'encode64 — Base64 encode the string. This message changes the value of the string. It will have the encoded string.',
75
+ 'decode64 — Decode the string from Base64. This message changes the value of the string. It will have the decoded string.',
76
+ 'escape — Escape the string to make it URL safe. This message changes the value of the string. It will have the escaped string.',
77
+ 'unescape — Unescape the string (from URL safe format). This message changes the value of the string. It will have the unescaped string.',
78
+ 'gen_uuid — Set the value of the string to a newly generated, random UUID. This message changes the value of the string.',
79
+ 'gen_alphanumeric ({len}) — Set the value of the string to a newly generated, random alphanumeric string. The {len} parameter is optional; the length is 10 if not specified. This message changes the value of the string.',
80
+ 'gen_hex ({len}) — Set the value of the string to a newly generated, random hex string. The {len} parameter is optional; the length is 10 if not specified. This message changes the value of the string.',
81
+ 'gen_base64 ({len}) — Set the value of the string to a newly generated, random base64 string. The {len} parameter is optional; the length is 12 if not specified. This message changes the value of the string.',
82
+ 'trim — Strip whitespace from the beginning and end of the string. This message changes the value of the string. It will have the trimmed string.',
83
+ 'sub ({from}, {to}) — Substitute the first occurrence of {from} with {to}. Both parameters are required. This message changes the value of the string. It will have the result.',
84
+ 'gsub ({from}, {to}) — Substitute all occurrences of {from} with {to}. Both parameters are required. This message changes the value of the string. It will have the result.',
85
+ 'page — Show the value in a pager (less), for viewing long content a screen at a time.'
86
+ ],
87
+ :examples => <<~EXAMPLES.strip
88
+ s [can] :
89
+ msg [string] : Hello World!
90
+ on_load [script] :
91
+ show s.msg
92
+ tell s.msg to up
93
+ show s.msg
94
+ tell s.msg to size
95
+ show it
96
+ EXAMPLES
97
+ }
51
98
  end
52
99
 
53
100
  end