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,148 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
3
+ #
4
+ # A URI (URL).
5
+ #
6
+ require 'uri'
7
+ require 'net/http'
8
+ require 'openssl'
9
+
10
+ module Gloo
11
+ module Objs
12
+ class Uri < Gloo::Core::Obj
13
+
14
+ KEYWORD = 'uri'.freeze
15
+ KEYWORD_SHORT = 'url'.freeze
16
+
17
+ #
18
+ # The name of the object type.
19
+ #
20
+ def self.typename
21
+ return KEYWORD
22
+ end
23
+
24
+ #
25
+ # The short name of the object type.
26
+ #
27
+ def self.short_typename
28
+ return KEYWORD_SHORT
29
+ end
30
+
31
+ #
32
+ # Set the value with any necessary type conversions.
33
+ #
34
+ def set_value( new_value )
35
+ self.value = new_value.to_s
36
+ end
37
+
38
+ #
39
+ # Does this object support multi-line values?
40
+ # Initially only true for scripts.
41
+ #
42
+ def multiline_value?
43
+ return false
44
+ end
45
+
46
+ # ---------------------------------------------------------------------
47
+ # Messages
48
+ # ---------------------------------------------------------------------
49
+
50
+ #
51
+ # Get a list of message names that this object receives.
52
+ #
53
+ def self.messages
54
+ basic = %w[open]
55
+ gets = %w[get_scheme get_host get_path]
56
+ more = %w[get_query get_fragment get_cert_expires]
57
+ return super + basic + gets + more
58
+ end
59
+
60
+ #
61
+ # Get the expiration date for the certificate.
62
+ #
63
+ def msg_get_cert_expires
64
+ return unless value
65
+ o = value
66
+ uri = URI( value )
67
+ response = Net::HTTP.start( uri.host, uri.port, :use_ssl => true )
68
+ cert = response.peer_cert
69
+ o = cert.not_after
70
+
71
+ @engine.heap.it.set_to o
72
+ return o
73
+ end
74
+
75
+ #
76
+ # Get the URI fragment that comes after the '#'
77
+ # in the URL. Might be used to scroll down in the page.
78
+ #
79
+ def msg_get_fragment
80
+ return unless value
81
+
82
+ o = URI( value ).fragment
83
+ @engine.heap.it.set_to o
84
+ return o
85
+ end
86
+
87
+ #
88
+ # Get the URI query parameters.
89
+ # Example: id=121
90
+ #
91
+ def msg_get_query
92
+ return unless value
93
+
94
+ o = URI( value ).query
95
+ @engine.heap.it.set_to o
96
+ return o
97
+ end
98
+
99
+ #
100
+ # Get the URI path.
101
+ # Example: /posts
102
+ #
103
+ def msg_get_path
104
+ return unless value
105
+
106
+ o = URI( value ).path
107
+ @engine.heap.it.set_to o
108
+ return o
109
+ end
110
+
111
+ #
112
+ # Get the URI host.
113
+ # Example: google.com
114
+ #
115
+ def msg_get_host
116
+ return unless value
117
+
118
+ o = URI( value ).host
119
+ @engine.heap.it.set_to o
120
+ return o
121
+ end
122
+
123
+ #
124
+ # Get the URI Scheme.
125
+ # Example: http
126
+ #
127
+ def msg_get_scheme
128
+ return unless value
129
+
130
+ o = URI( value ).scheme
131
+ @engine.heap.it.set_to o
132
+ return o
133
+ end
134
+
135
+ #
136
+ # Open the URI in the default browser.
137
+ #
138
+ def msg_open
139
+ return unless value
140
+
141
+ cmd = Gloo::Core::GlooSystem.open_for_platform
142
+ cmd_with_param = "#{cmd} \"#{value}\""
143
+ `#{cmd_with_param}`
144
+ end
145
+
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,87 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2022 Eric Crane. All rights reserved.
3
+ #
4
+ # Disc based mechanism for files.
5
+ # Provides interaction between the persistance classes and the OS
6
+ # file and folder system.
7
+ # This class might be overiden elsewhere to provide other mechanism.
8
+ # For example, in gloo-web, there will be a db based mechanism.
9
+ #
10
+
11
+ module Gloo
12
+ module Persist
13
+ class DiscMech
14
+
15
+ #
16
+ # Set up a disc based file mechanism.
17
+ #
18
+ def initialize( engine )
19
+ @engine = engine
20
+ end
21
+
22
+ #
23
+ # Get the default file extention.
24
+ #
25
+ def file_ext
26
+ return '.gloo'
27
+ end
28
+
29
+ #
30
+ # Get all the gloo files in the folder (partial path).
31
+ #
32
+ def get_all_files_in( folder )
33
+ pns = []
34
+ dir = File.join( @engine.settings.project_path, folder )
35
+ Dir.glob( "#{dir}*.gloo" ).each do |f|
36
+ pns << f
37
+ end
38
+ return pns
39
+ end
40
+
41
+ #
42
+ # Check if a file exists.
43
+ #
44
+ def exist?( file )
45
+ File.exist?( file )
46
+ end
47
+
48
+ #
49
+ # Check to see if the file is valid.
50
+ #
51
+ def valid?( file )
52
+ return false unless file
53
+ return false unless File.exist?( file )
54
+ return false unless File.file?( file )
55
+ return false unless file.end_with?( self.file_ext )
56
+
57
+ return true
58
+ end
59
+
60
+ #
61
+ # Expand a single file path.
62
+ #
63
+ def expand( name )
64
+ ext_path = File.expand_path( name )
65
+ return [ ext_path ] if self.valid?( ext_path )
66
+
67
+ full_name = "#{name}#{file_ext}"
68
+ return [ File.join( @engine.settings.project_path, full_name ) ]
69
+ end
70
+
71
+ #
72
+ # Read in the contents of a single file.
73
+ #
74
+ def read( file )
75
+ return File.read( file )
76
+ end
77
+
78
+ #
79
+ # Write data to the file.
80
+ #
81
+ def write( pn, data )
82
+ File.write( pn, data )
83
+ end
84
+
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,193 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
3
+ #
4
+ # Helper class used to load a file and create objects in the heap.
5
+ #
6
+
7
+ module Gloo
8
+ module Persist
9
+ class FileLoader
10
+
11
+ BEGIN_BLOCK = 'BEGIN'.freeze
12
+ END_BLOCK = 'END'.freeze
13
+ SPACE_CNT = 2
14
+
15
+ attr_reader :obj
16
+
17
+ #
18
+ # Set up a file storage for an object.
19
+ #
20
+ def initialize( engine, pn )
21
+ @engine = engine
22
+ @mech = @engine.platform.getFileMech( @engine )
23
+ @pn = pn
24
+ @tabs = 0
25
+ @obj = nil
26
+ @in_multiline = false
27
+ @exiting_multiline = false
28
+ @in_block = false
29
+ @block_value = ''
30
+ @debug = false
31
+ end
32
+
33
+ #
34
+ # Load the objects from the file.
35
+ #
36
+ def load
37
+ unless @mech.exist?( @pn )
38
+ @engine.log.error "File '#{@pn}' does not exist."
39
+ return
40
+ end
41
+
42
+ @engine.log.debug "Loading file '#{@pn}'"
43
+ @tabs = 0
44
+ @parent_stack = []
45
+ @parent = @engine.heap.root
46
+ @parent_stack.push @parent
47
+ f = @mech.read( @pn )
48
+ f.each_line do |line|
49
+ next if skip_line? line
50
+
51
+ handle_one_line line
52
+ end
53
+ end
54
+
55
+ #
56
+ # Process one one of the file we're loading.
57
+ #
58
+ def handle_one_line( line )
59
+ if line.strip.end_with? BEGIN_BLOCK
60
+ @in_block = true
61
+ @save_line = line
62
+ elsif @in_block
63
+ if line.strip == END_BLOCK
64
+ @in_block = false
65
+ determine_indent @save_line
66
+ process_line @save_line
67
+ else
68
+ @block_value << line
69
+ end
70
+ else
71
+ determine_indent line
72
+ process_line line
73
+ end
74
+ end
75
+
76
+ #
77
+ # Is this line a comment or a blank line?
78
+ # If so we'll skip it.
79
+ #
80
+ def skip_line?( line )
81
+ line = line.strip
82
+ return true if line.empty?
83
+ return true if line[ 0 ] == '#'
84
+
85
+ return false
86
+ end
87
+
88
+ #
89
+ # Determine the relative indent level for the line.
90
+ #
91
+ def determine_indent( line )
92
+ tabs = tab_count( line )
93
+ @indent = 0 # same level as prior line
94
+ if tabs > @tabs # indent
95
+ # TODO: What if indent is more than one more level?
96
+ @tabs = tabs
97
+ @indent = 1
98
+ elsif tabs < @tabs # outdent
99
+ diff = @tabs - tabs
100
+ @tabs -= diff
101
+ @indent -= diff
102
+ end
103
+ puts "tabs: #{@tabs}, indent: #{@indent}, line: #{line}" if @debug
104
+ end
105
+
106
+ #
107
+ # Process one line and add objects.
108
+ #
109
+ def process_line( line )
110
+ # reset multiline unless we're actually indented
111
+ if @in_multiline && @multi_indent > @indent
112
+ puts "Done multiline mi: #{@multi_indent}, i: #{@indent}" if @debug
113
+ @in_multiline = false
114
+ @exiting_multiline = true
115
+ end
116
+
117
+ if @in_multiline
118
+ @last.add_line line
119
+ else
120
+ setup_process_obj_line
121
+ process_obj_line line
122
+ end
123
+ end
124
+
125
+ #
126
+ # Setup and get ready to process an object line.
127
+ #
128
+ def setup_process_obj_line
129
+ if @exiting_multiline
130
+ @exiting_multiline = false
131
+ @indent += 1
132
+ end
133
+
134
+ if @indent.positive?
135
+ @parent = @last
136
+ @parent_stack.push @parent
137
+ elsif @indent.negative?
138
+ @indent.abs.times do
139
+ @parent_stack.pop
140
+ @parent = @parent_stack.last
141
+ end
142
+ end
143
+ end
144
+
145
+ #
146
+ # Process one line and add objects.
147
+ #
148
+ def process_obj_line( line )
149
+ name, type, value = split_line( line )
150
+ unless @block_value == ''
151
+ value = @block_value
152
+ @block_value = ''
153
+ end
154
+ params = { name: name, type: type, value: value, parent: @parent }
155
+ @last = @engine.factory.create( params )
156
+
157
+ if value.empty? && @last&.multiline_value?
158
+ @multi_indent = 0
159
+ @in_multiline = true
160
+ puts "*** Start multiline. multi_indent: #{@multi_indent}" if @debug
161
+ end
162
+
163
+ @obj = @last if @obj.nil?
164
+ end
165
+
166
+ #
167
+ # Get the number of leading tabs.
168
+ #
169
+ def tab_count( line )
170
+ i = 0
171
+
172
+ if line[ i ] == ' '
173
+ i += 1 while line[ i ] == ' '
174
+ tab_equiv = ( i / SPACE_CNT ).to_i
175
+ puts "Found #{i} spaces => #{tab_equiv}" if @debug
176
+ return tab_equiv
177
+ end
178
+
179
+ i += 1 while line[ i ] == "\t"
180
+ return i
181
+ end
182
+
183
+ #
184
+ # Split the line into 3 parts.
185
+ #
186
+ def split_line( line )
187
+ o = LineSplitter.new( line, @tabs )
188
+ return o.split
189
+ end
190
+
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,51 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
3
+ #
4
+ # Helper class used to save an object to a file..
5
+ #
6
+
7
+ module Gloo
8
+ module Persist
9
+ class FileSaver
10
+
11
+ #
12
+ # Set up a file storage for an object.
13
+ #
14
+ def initialize( engine, pn, obj )
15
+ @engine = engine
16
+ @mech = @engine.platform.getFileMech( @engine )
17
+ @pn = pn
18
+ @obj = obj
19
+ end
20
+
21
+ #
22
+ # Save the object to the file.
23
+ #
24
+ def save
25
+ data = get_obj( @obj )
26
+ @mech.write( @pn, data )
27
+ end
28
+
29
+ #
30
+ # Get string of tabs for indentation.
31
+ #
32
+ def tabs( indent = 0 )
33
+ return "\t" * indent
34
+ end
35
+
36
+ #
37
+ # Convert an object to textual representation.
38
+ # This is a recursive function.
39
+ #
40
+ def get_obj( obj, indent = 0 )
41
+ t = tabs( indent )
42
+ str = "#{t}#{obj.name} [#{obj.type_display}] : #{obj.value_display}\n"
43
+ obj.children.each do |child|
44
+ str << get_obj( child, indent + 1 )
45
+ end
46
+ return str
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,46 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
3
+ #
4
+ # Helper class takes an object and writes it to a file.
5
+ #
6
+
7
+ module Gloo
8
+ module Persist
9
+ class FileStorage
10
+
11
+ attr_reader :obj, :pn
12
+
13
+ #
14
+ # Set up a file storage for an object.
15
+ #
16
+ def initialize( engine, pn, obj = nil )
17
+ @engine = engine
18
+ @obj = obj
19
+ @pn = pn
20
+ end
21
+
22
+ #
23
+ # Save the object to the file.
24
+ #
25
+ def save
26
+ fs = FileSaver.new( @engine, @pn, @obj )
27
+ fs.save
28
+ end
29
+
30
+ #
31
+ # Load the object from the file.
32
+ #
33
+ def load
34
+ fl = FileLoader.new( @engine, @pn )
35
+ fl.load
36
+ @obj = fl.obj
37
+ if @obj
38
+ @engine.log.debug "Loaded object: #{@obj.name}"
39
+ else
40
+ @engine.log.error "Error loading file at #{@pn}"
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,81 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
3
+ #
4
+ # Helper class used as part of file loading.
5
+ # It is responsible for splitting a line into components.
6
+ #
7
+
8
+ module Gloo
9
+ module Persist
10
+ class LineSplitter
11
+
12
+ BEGIN_BLOCK = 'BEGIN'.freeze
13
+ END_BLOCK = 'END'.freeze
14
+
15
+ attr_reader :obj
16
+
17
+ #
18
+ # Set up a line splitter
19
+ #
20
+ def initialize( line, tabs )
21
+ @line = line
22
+ @tabs = tabs
23
+ end
24
+
25
+ #
26
+ # Split the line into 3 parts.
27
+ #
28
+ def split
29
+ detect_name
30
+ detect_type
31
+ detect_value
32
+
33
+ return @name, @type, @value
34
+ end
35
+
36
+ #
37
+ # Detect the object name.
38
+ #
39
+ def detect_name
40
+ @line = @line.strip
41
+ @idx = @line.index( ' ' )
42
+ @name = @line[ 0..@idx - 1 ]
43
+ end
44
+
45
+ #
46
+ # Detect the object type.
47
+ #
48
+ def detect_type
49
+ @line = @line[ @idx + 1..-1 ]
50
+ @idx = @line.index( ' ' )
51
+
52
+ if @line[ 0 ] == ':'
53
+ @type = 'untyped'
54
+ return
55
+ end
56
+
57
+ @type = @line[ 0..( @idx ? @idx - 1 : -1 ) ]
58
+ @type = @type[ 1..-1 ] if @type[ 0 ] == '['
59
+ @type = @type[ 0..-2 ] if @type[ -1 ] == ']'
60
+ end
61
+
62
+ #
63
+ # Detect the object value.
64
+ # Use nil if there is no value specified.
65
+ #
66
+ def detect_value
67
+ if @idx
68
+ @value = @line[ @idx + 1..-1 ]
69
+ if @value[ 0..1 ] == ': '
70
+ @value = @value[ 2..-1 ]
71
+ elsif @value[ 0 ] == ':'
72
+ @value = @value[ 1..-1 ]
73
+ end
74
+ else
75
+ @value = nil
76
+ end
77
+ end
78
+
79
+ end
80
+ end
81
+ end