gloo 1.4.2 → 2.0.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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/.DS_Store +0 -0
  3. data/.gitignore +1 -0
  4. data/gloo.gemspec +0 -2
  5. data/lib/VERSION +1 -1
  6. data/lib/dependencies.rb +4 -4
  7. data/lib/gloo/app/args.rb +112 -0
  8. data/lib/gloo/app/engine.rb +247 -0
  9. data/lib/gloo/app/engine_context.rb +25 -0
  10. data/lib/gloo/app/info.rb +20 -3
  11. data/lib/gloo/app/log.rb +73 -1
  12. data/lib/gloo/app/mode.rb +27 -0
  13. data/lib/gloo/app/platform.rb +8 -1
  14. data/lib/gloo/app/settings.rb +202 -0
  15. data/lib/gloo/convert/converter.rb +42 -0
  16. data/lib/gloo/convert/string_to_date.rb +21 -0
  17. data/lib/gloo/convert/string_to_datetime.rb +21 -0
  18. data/lib/gloo/convert/string_to_decimal.rb +20 -0
  19. data/lib/gloo/convert/string_to_integer.rb +20 -0
  20. data/lib/gloo/convert/string_to_time.rb +21 -0
  21. data/lib/gloo/core/baseo.rb +31 -0
  22. data/lib/gloo/core/dictionary.rb +245 -0
  23. data/lib/gloo/core/error.rb +61 -0
  24. data/lib/gloo/core/event_manager.rb +45 -0
  25. data/lib/gloo/core/factory.rb +211 -0
  26. data/lib/gloo/core/gloo_system.rb +267 -0
  27. data/lib/gloo/core/heap.rb +53 -0
  28. data/lib/gloo/core/here.rb +36 -0
  29. data/lib/gloo/core/it.rb +36 -0
  30. data/lib/gloo/core/literal.rb +30 -0
  31. data/lib/gloo/core/obj.rb +318 -0
  32. data/lib/gloo/core/obj_finder.rb +30 -0
  33. data/lib/gloo/core/op.rb +40 -0
  34. data/lib/gloo/core/parser.rb +60 -0
  35. data/lib/gloo/core/pn.rb +212 -0
  36. data/lib/gloo/core/tokens.rb +165 -0
  37. data/lib/gloo/core/verb.rb +87 -0
  38. data/lib/gloo/exec/action.rb +48 -0
  39. data/lib/gloo/exec/dispatch.rb +40 -0
  40. data/lib/gloo/exec/exec_env.rb +75 -0
  41. data/lib/gloo/exec/runner.rb +45 -0
  42. data/lib/gloo/exec/script.rb +50 -0
  43. data/lib/gloo/exec/stack.rb +79 -0
  44. data/lib/gloo/expr/expression.rb +119 -0
  45. data/lib/gloo/expr/l_boolean.rb +36 -0
  46. data/lib/gloo/expr/l_decimal.rb +39 -0
  47. data/lib/gloo/expr/l_integer.rb +37 -0
  48. data/lib/gloo/expr/l_string.rb +58 -0
  49. data/lib/gloo/expr/op_div.rb +22 -0
  50. data/lib/gloo/expr/op_minus.rb +22 -0
  51. data/lib/gloo/expr/op_mult.rb +22 -0
  52. data/lib/gloo/expr/op_plus.rb +24 -0
  53. data/lib/gloo/objs/basic/alias.rb +78 -0
  54. data/lib/gloo/objs/basic/boolean.rb +120 -0
  55. data/lib/gloo/objs/basic/container.rb +65 -0
  56. data/lib/gloo/objs/basic/decimal.rb +76 -0
  57. data/lib/gloo/objs/basic/integer.rb +73 -0
  58. data/lib/gloo/objs/basic/script.rb +99 -0
  59. data/lib/gloo/objs/basic/string.rb +77 -0
  60. data/lib/gloo/objs/basic/text.rb +79 -0
  61. data/lib/gloo/objs/basic/untyped.rb +41 -0
  62. data/lib/gloo/objs/cli/banner.rb +1 -1
  63. data/lib/gloo/objs/cli/bar.rb +3 -3
  64. data/lib/gloo/objs/cli/colorize.rb +1 -1
  65. data/lib/gloo/objs/cli/confirm.rb +1 -1
  66. data/lib/gloo/objs/cli/menu.rb +6 -6
  67. data/lib/gloo/objs/cli/menu_item.rb +1 -1
  68. data/lib/gloo/objs/cli/pastel.rb +1 -1
  69. data/lib/gloo/objs/cli/prompt.rb +1 -1
  70. data/lib/gloo/objs/cli/select.rb +2 -2
  71. data/lib/gloo/objs/ctrl/each.rb +279 -0
  72. data/lib/gloo/objs/ctrl/repeat.rb +108 -0
  73. data/lib/gloo/objs/data/markdown.rb +79 -0
  74. data/lib/gloo/objs/data/mysql.rb +5 -5
  75. data/lib/gloo/objs/data/query.rb +4 -4
  76. data/lib/gloo/objs/data/sqlite.rb +1 -1
  77. data/lib/gloo/objs/data/table.rb +112 -0
  78. data/lib/gloo/objs/dev/git.rb +2 -2
  79. data/lib/gloo/objs/dev/stats.rb +4 -4
  80. data/lib/gloo/objs/dt/date.rb +65 -0
  81. data/lib/gloo/objs/dt/datetime.rb +120 -0
  82. data/lib/gloo/objs/dt/dt_tools.rb +100 -0
  83. data/lib/gloo/objs/dt/time.rb +65 -0
  84. data/lib/gloo/objs/ror/erb.rb +116 -0
  85. data/lib/gloo/objs/ror/eval.rb +107 -0
  86. data/lib/gloo/objs/snd/play.rb +1 -1
  87. data/lib/gloo/objs/snd/say.rb +1 -1
  88. data/lib/gloo/objs/system/file_handle.rb +4 -4
  89. data/lib/gloo/objs/system/ssh_exec.rb +1 -1
  90. data/lib/gloo/objs/system/system.rb +1 -1
  91. data/lib/gloo/objs/web/http_get.rb +159 -0
  92. data/lib/gloo/objs/web/http_post.rb +183 -0
  93. data/lib/gloo/objs/web/json.rb +135 -0
  94. data/lib/gloo/objs/web/slack.rb +130 -0
  95. data/lib/gloo/objs/web/teams.rb +117 -0
  96. data/lib/gloo/objs/web/uri.rb +148 -0
  97. data/lib/gloo/persist/disc_mech.rb +87 -0
  98. data/lib/gloo/persist/file_loader.rb +193 -0
  99. data/lib/gloo/persist/file_saver.rb +51 -0
  100. data/lib/gloo/persist/file_storage.rb +46 -0
  101. data/lib/gloo/persist/line_splitter.rb +81 -0
  102. data/lib/gloo/persist/persist_man.rb +153 -0
  103. data/lib/gloo/utils/format.rb +21 -0
  104. data/lib/gloo/utils/stats.rb +206 -0
  105. data/lib/gloo/utils/words.rb +19 -0
  106. data/lib/gloo/verbs/alert.rb +2 -2
  107. data/lib/gloo/verbs/beep.rb +1 -1
  108. data/lib/gloo/verbs/cls.rb +1 -1
  109. data/lib/gloo/verbs/context.rb +62 -0
  110. data/lib/gloo/verbs/create.rb +68 -0
  111. data/lib/gloo/verbs/execute.rb +56 -0
  112. data/lib/gloo/verbs/files.rb +49 -0
  113. data/lib/gloo/verbs/help.rb +1 -1
  114. data/lib/gloo/verbs/if.rb +92 -0
  115. data/lib/gloo/verbs/list.rb +98 -0
  116. data/lib/gloo/verbs/load.rb +45 -0
  117. data/lib/gloo/verbs/move.rb +89 -0
  118. data/lib/gloo/verbs/put.rb +94 -0
  119. data/lib/gloo/verbs/quit.rb +40 -0
  120. data/lib/gloo/verbs/reload.rb +43 -0
  121. data/lib/gloo/verbs/run.rb +75 -0
  122. data/lib/gloo/verbs/save.rb +39 -0
  123. data/lib/gloo/verbs/show.rb +63 -0
  124. data/lib/gloo/verbs/tell.rb +80 -0
  125. data/lib/gloo/verbs/unless.rb +92 -0
  126. data/lib/gloo/verbs/unload.rb +46 -0
  127. data/lib/gloo/verbs/version.rb +3 -3
  128. data/lib/gloo/verbs/wait.rb +42 -0
  129. data/lib/gloo.rb +2 -2
  130. data/lib/run.rb +2 -2
  131. metadata +97 -22
@@ -0,0 +1,318 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
3
+ #
4
+ # An data/value object.
5
+ # Derives from the Baseo object. Is not a verb.
6
+ #
7
+
8
+ module Gloo
9
+ module Core
10
+ class Obj < Baseo
11
+
12
+ attr_accessor :value
13
+ attr_reader :children, :parent
14
+
15
+ #
16
+ # Set up the object.
17
+ #
18
+ def initialize( engine )
19
+ @engine = engine
20
+ @value = ''
21
+ @children = []
22
+ @parent = nil
23
+ end
24
+
25
+ #
26
+ # Register object types when they are loaded.
27
+ #
28
+ def self.inherited( subclass )
29
+ Dictionary.instance.register_obj( subclass )
30
+ end
31
+
32
+ #
33
+ # The name of the object type.
34
+ #
35
+ def self.typename
36
+ raise 'this method should be overriden'
37
+ end
38
+
39
+ #
40
+ # The object type, suitable for display.
41
+ #
42
+ def type_display
43
+ return self.class.typename
44
+ end
45
+
46
+ #
47
+ # Set the parent for the object.
48
+ #
49
+ def set_parent( obj )
50
+ @parent = obj
51
+ end
52
+
53
+ #
54
+ # Is this the root object?
55
+ #
56
+ def root?
57
+ return false if @parent
58
+ return false unless name.downcase == 'root'
59
+
60
+ return true
61
+ end
62
+
63
+ # Can this object be created?
64
+ # This is true by default and only false for some special cases
65
+ # such as the System object.
66
+ def self.can_create?
67
+ true
68
+ end
69
+
70
+ #
71
+ # Get the path and name to this object.
72
+ #
73
+ def pn
74
+ str = self.name
75
+ p = self.parent
76
+ while p && !p.root?
77
+ str = "#{p.name}.#{str}"
78
+ p = p.parent
79
+ end
80
+ return str
81
+ end
82
+
83
+ #
84
+ # Generic function to get display value.
85
+ # Can be used for debugging, etc.
86
+ #
87
+ def display_value
88
+ return self.pn
89
+ end
90
+
91
+ # ---------------------------------------------------------------------
92
+ # Value
93
+ # ---------------------------------------------------------------------
94
+
95
+ #
96
+ # Set the value with any necessary type conversions.
97
+ #
98
+ def set_value( new_value )
99
+ self.value = new_value
100
+ end
101
+
102
+ #
103
+ # Get the value for display purposes.
104
+ #
105
+ def value_display
106
+ return self.value.to_s
107
+ end
108
+
109
+ #
110
+ # Does this object support multi-line values?
111
+ # Initially only true for scripts.
112
+ #
113
+ def multiline_value?
114
+ return false
115
+ end
116
+
117
+ #
118
+ # Is the value a String?
119
+ #
120
+ def value_string?
121
+ return self.value.is_a? String
122
+ end
123
+
124
+ #
125
+ # Is the value an Array?
126
+ #
127
+ def value_is_array?
128
+ return self.value.is_a? Array
129
+ end
130
+
131
+ #
132
+ # Is the value a blank string?
133
+ #
134
+ def value_is_blank?
135
+ return true if value.nil?
136
+
137
+ return self.value.to_s.strip.empty?
138
+ end
139
+
140
+ # ---------------------------------------------------------------------
141
+ # Children
142
+ # ---------------------------------------------------------------------
143
+
144
+ #
145
+ # Find a child of the given name.
146
+ # If found, return it. If not found create it.
147
+ #
148
+ def find_add_child( name, type )
149
+ child = self.find_child( name )
150
+ return child if child
151
+
152
+ params = { :name => name,
153
+ :type => type,
154
+ :value => nil,
155
+ :parent => self }
156
+ return @engine.factory.create params
157
+ end
158
+
159
+ #
160
+ # Add a child object to the container.
161
+ #
162
+ def add_child( obj )
163
+ @children << obj
164
+ obj.set_parent self
165
+ end
166
+
167
+ #
168
+ # Get the number of children.
169
+ #
170
+ def child_count
171
+ return @children.count
172
+ end
173
+
174
+ #
175
+ # Does this object contain an object with the given name?
176
+ #
177
+ def contains_child?( name )
178
+ @children.each do |o|
179
+ return true if name.downcase == o.name.downcase
180
+ end
181
+ return false
182
+ end
183
+
184
+ #
185
+ # Find a child object with the given name.
186
+ #
187
+ def find_child( name )
188
+ if name.end_with?( Gloo::Objs::Alias::ALIAS_REFERENCE )
189
+ name = name[ 0..-2 ]
190
+ end
191
+
192
+ @children.each do |o|
193
+ return o if name.downcase == o.name.downcase
194
+ end
195
+
196
+ if self.type_display == Gloo::Objs::Alias.typename
197
+ ln = Gloo::Core::Pn.new( @engine, self.value )
198
+ redirect = ln.resolve
199
+ return redirect.find_child( name )
200
+ end
201
+ return nil
202
+ end
203
+
204
+ #
205
+ # Delete all children from the container.
206
+ #
207
+ def delete_children
208
+ @children.reverse.each do |o|
209
+ self.remove_child o
210
+ end
211
+ end
212
+
213
+ #
214
+ # Remove the object from the children collection.
215
+ #
216
+ def remove_child( obj )
217
+ @children.delete obj
218
+ end
219
+
220
+ # Does this object have children to add when an object
221
+ # is created in interactive mode?
222
+ # This does not apply during obj load, etc.
223
+ def add_children_on_create?
224
+ return false
225
+ end
226
+
227
+ # Add children to this object.
228
+ # This is used by containers to add children needed
229
+ # for default configurations.
230
+ def add_default_children
231
+ # Override this.
232
+ end
233
+
234
+ # ---------------------------------------------------------------------
235
+ # Messages
236
+ # ---------------------------------------------------------------------
237
+
238
+ #
239
+ # Get a list of message names that this object receives.
240
+ #
241
+ def self.messages
242
+ return %w[reload unload]
243
+ end
244
+
245
+ #
246
+ # Can this object receive a message?
247
+ #
248
+ def can_receive_message?( msg )
249
+ msgs = self.class.messages
250
+ return msgs.include?( msg.strip.downcase )
251
+ end
252
+
253
+ #
254
+ # Sent this object the given message.
255
+ #
256
+ def send_message( msg, params = nil )
257
+ @params = params
258
+ return self.dispatch msg if self.can_receive_message? msg
259
+
260
+ @engine.log.error "Object #{self.name} cannot receive message #{msg}"
261
+ return false
262
+ end
263
+
264
+ #
265
+ # Dispatch the message to the object.
266
+ #
267
+ def dispatch( msg )
268
+ o = "msg_#{msg}"
269
+ if self.respond_to? o
270
+ self.public_send( o )
271
+ return true
272
+ else
273
+ @engine.log.error "Message #{msg} not implemented"
274
+ return false
275
+ end
276
+ end
277
+
278
+ #
279
+ # Send the object the unload message.
280
+ #
281
+ def msg_unload
282
+ if self.root?
283
+ @engine.log.error 'Cannot unload the root object.'
284
+ return
285
+ end
286
+
287
+ @engine.event_manager.on_unload self
288
+ @engine.heap.unload self
289
+ @engine.persist_man.unload self
290
+ end
291
+
292
+ #
293
+ # Send the object the reload message.
294
+ # Note that this will only work for objects with file assoications.
295
+ #
296
+ def msg_reload
297
+ if self.root?
298
+ @engine.log.error 'Cannot reload the root object.'
299
+ return
300
+ end
301
+
302
+ @engine.persist_man.reload self
303
+ end
304
+
305
+ # ---------------------------------------------------------------------
306
+ # Help
307
+ # ---------------------------------------------------------------------
308
+
309
+ #
310
+ # Get help for this object.
311
+ #
312
+ def self.help
313
+ return 'No help found.'
314
+ end
315
+
316
+ end
317
+ end
318
+ end
@@ -0,0 +1,30 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
3
+ #
4
+ # Utility used to find objects.
5
+ #
6
+
7
+ module Gloo
8
+ module Core
9
+ class ObjFinder
10
+
11
+ #
12
+ # Find all objects in the given container that have
13
+ # the given name.
14
+ # If the container isn't provided, root will be used.
15
+ #
16
+ def self.by_name( engine, name, container = nil )
17
+ container = engine.heap.root if container.nil?
18
+ arr = []
19
+
20
+ container.children.each do |o|
21
+ arr << o if o.name == name
22
+ arr += by_name( engine, name, o ) if o.child_count.positive?
23
+ end
24
+
25
+ return arr
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
3
+ #
4
+ # An Operator; part of an expression.
5
+ # A static helper class.
6
+ #
7
+
8
+ module Gloo
9
+ module Core
10
+ class Op
11
+
12
+ #
13
+ # Is the token an operator?
14
+ #
15
+ def self.op?( token )
16
+ return [ '+', '-', '*', '/' ].include?( token.strip )
17
+ end
18
+
19
+ #
20
+ # Create the operator for the given token.
21
+ #
22
+ def self.create_op( token )
23
+ return Gloo::Expr::OpMinus.new if token == '-'
24
+ return Gloo::Expr::OpMult.new if token == '*'
25
+ return Gloo::Expr::OpDiv.new if token == '/'
26
+ return Gloo::Expr::OpPlus.new if token == '+'
27
+
28
+ return default_op
29
+ end
30
+
31
+ #
32
+ # Get the default operator (+).
33
+ #
34
+ def self.default_op
35
+ return Gloo::Expr::OpPlus.new
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,60 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
3
+ #
4
+ # The Parser.
5
+ # Can parse single line commands or files.
6
+ #
7
+
8
+ module Gloo
9
+ module Core
10
+ class Parser
11
+
12
+ #
13
+ # Set up the parser.
14
+ #
15
+ def initialize( engine )
16
+ @engine = engine
17
+ @engine.log.debug 'parser intialized...'
18
+ end
19
+
20
+ #
21
+ # Parse a command from the immediate execution context.
22
+ #
23
+ def parse_immediate( cmd )
24
+ cmd, params = split_params cmd
25
+ params = Gloo::Core::Tokens.new( params ) if params
26
+ tokens = Gloo::Core::Tokens.new( cmd )
27
+ dic = Gloo::Core::Dictionary.instance
28
+ verb = dic.find_verb( tokens.verb )
29
+ return verb.new( @engine, tokens, params ) if verb
30
+
31
+ @engine.log.error "Verb '#{tokens.verb}' was not found."
32
+ return nil
33
+ end
34
+
35
+ #
36
+ # If additional params were provided, split them out
37
+ # from the token list.
38
+ #
39
+ def split_params( cmd )
40
+ params = nil
41
+ i = cmd.rindex( '(' )
42
+ if i && cmd.strip.end_with?( ')' )
43
+ pstr = cmd[ i + 1..-1 ]
44
+ params = pstr.strip[ 0..-2 ] if pstr
45
+ cmd = cmd[ 0, i - 1 ]
46
+ end
47
+ return cmd, params
48
+ end
49
+
50
+ #
51
+ # Parse a command and then run it if it parsed correctly.
52
+ #
53
+ def run( cmd )
54
+ v = parse_immediate( cmd )
55
+ Gloo::Exec::Runner.go( @engine, v ) if v
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,212 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
3
+ #
4
+ # An object path name.
5
+ # Path and name elements are separated by periods.
6
+ #
7
+
8
+ module Gloo
9
+ module Core
10
+ class Pn < Baseo
11
+
12
+ ROOT = 'root'.freeze
13
+ IT = 'it'.freeze
14
+ ERROR = 'error'.freeze
15
+ CONTEXT = '@'.freeze
16
+
17
+ attr_reader :src, :elements
18
+
19
+ #
20
+ # Set up the object given a source string,
21
+ # ie: the full path and name.
22
+ #
23
+ def initialize( engine, src )
24
+ @engine = engine
25
+ set_to src
26
+ end
27
+
28
+ #
29
+ # Reference to the root object path.
30
+ #
31
+ def self.root( engine )
32
+ return Pn.new( engine, ROOT )
33
+ end
34
+
35
+ #
36
+ # Reference to it.
37
+ #
38
+ def self.it( engine )
39
+ return Pn.new( engine, IT )
40
+ end
41
+
42
+ #
43
+ # Reference to the error message.
44
+ #
45
+ def self.error( engine )
46
+ return Pn.new( engine, ERROR )
47
+ end
48
+
49
+ #
50
+ # Does the pathname reference refer to the root?
51
+ #
52
+ def root?
53
+ return @src.downcase == ROOT
54
+ end
55
+
56
+ #
57
+ # Does the pathname reference refer to it?
58
+ #
59
+ def it?
60
+ return @src.downcase == IT
61
+ end
62
+
63
+ #
64
+ # Does the pathname reference refer to error?
65
+ #
66
+ def error?
67
+ return @src.downcase == ERROR
68
+ end
69
+
70
+ #
71
+ # Does the pathname reference refer to the gloo system object?
72
+ #
73
+ def gloo_sys?
74
+ return false unless @elements&.count&.positive?
75
+
76
+ o = @elements.first.downcase
77
+ return true if o == Gloo::Core::GlooSystem.typename
78
+ return true if o == Gloo::Core::GlooSystem.short_typename
79
+
80
+ return false
81
+ end
82
+
83
+ #
84
+ # Get the string representation of the pathname.
85
+ #
86
+ def to_s
87
+ return @src
88
+ end
89
+
90
+ #
91
+ # Set the object pathname to the given value.
92
+ #
93
+ def set_to( value )
94
+ @src = value.nil? ? nil : value.strip
95
+ @elements = @src.nil? ? [] : @src.split( '.' )
96
+ end
97
+
98
+ #
99
+ # Convert the raw string to a list of segments.
100
+ #
101
+ def segments
102
+ return @elements
103
+ end
104
+
105
+ #
106
+ # Get the name element.
107
+ #
108
+ def name
109
+ return '' unless self.named?
110
+
111
+ return @elements.last
112
+ end
113
+
114
+ #
115
+ # Does the value include path elements?
116
+ #
117
+ def named?
118
+ return @elements.count.positive?
119
+ end
120
+
121
+ #
122
+ # Does the value include a name?
123
+ #
124
+ def includes_path?
125
+ return @elements.count > 1
126
+ end
127
+
128
+ #
129
+ # Does the path start with the context?
130
+ #
131
+ def includes_context?
132
+ return @src.start_with?( "#{CONTEXT}." )
133
+ end
134
+
135
+ #
136
+ # Expand the context so we have the full path.
137
+ #
138
+ def expand_context
139
+ # return unless @engine.heap.context
140
+ self.set_to( "#{@engine.heap.context}#{@src[1..-1]}" )
141
+ end
142
+
143
+ #
144
+ # Get the parent that contains the object referenced.
145
+ #
146
+ def get_parent
147
+ o = @engine.heap.root
148
+
149
+ if self.includes_path?
150
+ @elements[ 0..-2 ].each do |e|
151
+ o = o.find_child( e )
152
+ if o.nil?
153
+ @engine.log.error "Object '#{e}' was not found."
154
+ return nil
155
+ end
156
+ end
157
+ end
158
+
159
+ return o
160
+ end
161
+
162
+ #
163
+ # Does the object at the path exist?
164
+ #
165
+ def exists?
166
+ return true if self.root?
167
+ return true if self.it?
168
+ return true if self.error?
169
+
170
+ parent = self.get_parent
171
+ return false unless parent
172
+
173
+ return parent.contains_child? name
174
+ end
175
+
176
+ #
177
+ # Is the reference to a color?
178
+ #
179
+ def named_color?
180
+ colors = %w[red blue green white black yellow]
181
+ return true if colors.include?( @src.downcase )
182
+ end
183
+
184
+ #
185
+ # Resolve the pathname reference.
186
+ # Find the object referenced or return nil if it is not found.
187
+ #
188
+ def resolve
189
+ return @engine.heap.root if self.root?
190
+ return @engine.heap.it if self.it?
191
+ return @engine.heap.error if self.error?
192
+ return Gloo::Core::GlooSystem.new(
193
+ @engine, self ) if self.gloo_sys?
194
+
195
+ if Here.includes_here_ref?( @elements )
196
+ Here.expand_here( @engine, self )
197
+ end
198
+
199
+ if self.includes_context?
200
+ expand_context
201
+ end
202
+
203
+ parent = self.get_parent
204
+ return nil unless parent
205
+
206
+ obj = parent.find_child( self.name )
207
+ return Gloo::Objs::Alias.resolve_alias( @engine, obj, self.src )
208
+ end
209
+
210
+ end
211
+ end
212
+ end