rookout 0.1.28 → 0.1.50

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rookout/augs/actions/action_run_processor.rb +1 -0
  3. data/lib/rookout/augs/aug.rb +7 -6
  4. data/lib/rookout/augs/aug_factory.rb +71 -19
  5. data/lib/rookout/augs/aug_rate_limiter.rb +35 -36
  6. data/lib/rookout/augs/limits_manager.rb +32 -0
  7. data/lib/rookout/augs/locations/location.rb +1 -1
  8. data/lib/rookout/augs/locations/location_file_line.rb +5 -1
  9. data/lib/rookout/com_ws/agent_com_ws.rb +24 -20
  10. data/lib/rookout/com_ws/command_handler.rb +1 -1
  11. data/lib/rookout/com_ws/envelope_wrapper.rb +68 -0
  12. data/lib/rookout/com_ws/git.rb +1 -1
  13. data/lib/rookout/com_ws/information.rb +45 -1
  14. data/lib/rookout/com_ws/output.rb +62 -12
  15. data/lib/rookout/commit.rb +1 -1
  16. data/lib/rookout/config.rb +86 -15
  17. data/lib/rookout/exceptions.rb +49 -10
  18. data/lib/rookout/interface.rb +10 -8
  19. data/lib/rookout/logger.rb +13 -7
  20. data/lib/rookout/processor/namespace_serializer.rb +1 -1
  21. data/lib/rookout/processor/namespace_serializer2.rb +331 -0
  22. data/lib/rookout/processor/namespaces/container_namespace.rb +5 -0
  23. data/lib/rookout/processor/namespaces/frame_namespace.rb +2 -3
  24. data/lib/rookout/processor/namespaces/namespace.rb +1 -0
  25. data/lib/rookout/processor/namespaces/noop_namespace.rb +0 -4
  26. data/lib/rookout/processor/namespaces/ruby_object_namespace.rb +37 -22
  27. data/lib/rookout/processor/namespaces/ruby_object_serializer.rb +9 -7
  28. data/lib/rookout/processor/namespaces/ruby_utils_namespace.rb +0 -4
  29. data/lib/rookout/processor/namespaces/stack_namespace.rb +1 -0
  30. data/lib/rookout/processor/namespaces/traceback_namespace.rb +5 -0
  31. data/lib/rookout/processor/operations/set_operation.rb +2 -0
  32. data/lib/rookout/processor/paths/arithmetic_path.rb +4 -2
  33. data/lib/rookout/processor/paths/canopy/actions.rb +5 -1
  34. data/lib/rookout/processor/paths/canopy/consts.rb +6 -4
  35. data/lib/rookout/processor/paths/canopy/markers.rb +15 -5
  36. data/lib/rookout/processor/processor_factory.rb +0 -2
  37. data/lib/rookout/processor/rook_error.rb +3 -1
  38. data/lib/rookout/protobuf/controller_info_pb.rb +1 -0
  39. data/lib/rookout/protobuf/messages_pb.rb +54 -0
  40. data/lib/rookout/protobuf/variant2_pb.rb +42 -0
  41. data/lib/rookout/protobuf/variant_pb.rb +22 -0
  42. data/lib/rookout/rookout_singleton.rb +4 -3
  43. data/lib/rookout/sanitizer.rb +22 -0
  44. data/lib/rookout/services/position.rb +4 -3
  45. data/lib/rookout/services/tracer.rb +5 -2
  46. data/lib/rookout/utils.rb +28 -14
  47. data/lib/rookout/version.rb +1 -1
  48. data/lib/rookout.rb +4 -0
  49. metadata +46 -13
@@ -0,0 +1,331 @@
1
+ module Rookout
2
+ module Processor
3
+ class NamespaceSerializer2
4
+ require_relative "../logger"
5
+
6
+ require_relative "../protobuf/variant_pb"
7
+ require_relative "../protobuf/variant2_pb"
8
+ require_relative "../user_warnings"
9
+ require_relative "./namespaces/container_namespace"
10
+ require_relative "./namespaces/traceback_namespace"
11
+
12
+ begin
13
+ require "hashie/mash"
14
+ MASH = ::Hashie::Mash
15
+ rescue LoadError
16
+ MASH = nil
17
+ end
18
+
19
+ begin
20
+ require "active_support/core_ext/hash/indifferent_access"
21
+ HASH_WITH_INDIFFERENT_ACCESS = ActiveSupport::HashWithIndifferentAccess
22
+ rescue LoadError
23
+ HASH_WITH_INDIFFERENT_ACCESS = nil
24
+ end
25
+
26
+ def initialize
27
+ @string_cache = {}
28
+ @estimated_pending_bytes = 0
29
+ end
30
+
31
+ attr_reader :string_cache
32
+ attr_reader :estimated_pending_bytes
33
+
34
+ def get_string_index_in_cache str
35
+ if @string_cache.key? str
36
+ @string_cache[str]
37
+ else
38
+ @estimated_pending_bytes += str.length + 5
39
+ current_size = @string_cache.size
40
+ @string_cache.store str, current_size
41
+ current_size
42
+ end
43
+ end
44
+
45
+ def dump_variant_type variant, type
46
+ variant.variant_type_max_depth = type << 1
47
+ @estimated_pending_bytes += 2 # Field header + short number
48
+ end
49
+
50
+ def dump_variant_type_max_depth variant, type
51
+ variant.variant_type_max_depth = (type << 1) | 1
52
+ @estimated_pending_bytes += 2 # Field header + short number
53
+ end
54
+
55
+ def dump namespace, log_errors
56
+ case namespace
57
+ when Namespaces::RubyObjectNamespace
58
+ dump_ruby_object_namespace namespace, log_errors
59
+ when Namespaces::ContainerNamespace
60
+ dump_container_namespace namespace, log_errors
61
+ when Namespaces::TracebackNamespace
62
+ dump_traceback_namespace namespace
63
+ else
64
+ raise NotImplementedError
65
+ end
66
+ rescue StandardError => e
67
+ message = "Failed to serialize namespace"
68
+ variant = Com::Rookout::Variant2.new
69
+ @estimated_pending_bytes = 0
70
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_ERROR
71
+
72
+ if log_errors
73
+ Logger.instance.exception message, e
74
+
75
+ error = RookError.new e, message
76
+ UserWarnings.notify_warning error
77
+ end
78
+ variant
79
+ end
80
+
81
+ def dump_ruby_object_namespace namespace, log_errors
82
+ dump_raw_object namespace.obj, 0, namespace.dump_config, log_errors
83
+ end
84
+
85
+ def dump_raw_object obj, current_depth, config, log_object_errors
86
+ unsafe_dump_object obj, current_depth, config, log_object_errors
87
+ rescue StandardError => e
88
+ message = "Failed to serialize object"
89
+ variant = Com::Rookout::Variant2.new
90
+ @estimated_pending_bytes = 0
91
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_ERROR
92
+
93
+ if log_object_errors
94
+ Logger.instance.exception message, e
95
+
96
+ error = RookError.new e, message
97
+ UserWarnings.notify_warning error
98
+ end
99
+ variant
100
+ end
101
+
102
+ # rubocop:disable Metrics/AbcSize
103
+ # rubocop:disable Metrics/PerceivedComplexity
104
+ # rubocop:disable Metrics/CyclomaticComplexity
105
+ # rubocop:disable Style/ClassEqualityComparison
106
+ def unsafe_dump_object obj, current_depth, config, log_object_errors
107
+ variant = Com::Rookout::Variant2.new original_type_index_in_cache: get_string_index_in_cache(obj.class.to_s)
108
+
109
+ if obj.nil?
110
+ dump_nil variant
111
+ elsif obj.is_a?(Numeric) || obj.is_a?(TrueClass) || obj.is_a?(FalseClass)
112
+ dump_numeric obj, variant, config
113
+ elsif obj.is_a?(String) || obj.is_a?(Symbol)
114
+ dump_string obj, variant, config
115
+ elsif obj.is_a? Time
116
+ dump_time obj, variant
117
+ elsif obj.class == Array
118
+ dump_array obj, variant, current_depth, config, log_object_errors
119
+ elsif obj.class == Hash || (!MASH.nil? && obj.is_a?(MASH)) ||
120
+ (!HASH_WITH_INDIFFERENT_ACCESS.nil? && obj.is_a?(HASH_WITH_INDIFFERENT_ACCESS))
121
+ dump_hash obj, variant, current_depth, config, log_object_errors
122
+ elsif obj.is_a? Exception
123
+ dump_exception obj, variant, current_depth, config, log_object_errors
124
+ elsif obj.is_a?(Method) || obj.is_a?(Proc) || obj.is_a?(Class) || obj.is_a?(Module)
125
+ dump_code_object obj, variant
126
+ else
127
+ dump_user_class variant, obj, current_depth, config, log_object_errors
128
+ end
129
+
130
+ variant
131
+ end
132
+ # rubocop:enable Style/ClassEqualityComparison
133
+ # rubocop:enable Metrics/AbcSize
134
+ # rubocop:enable Metrics/PerceivedComplexity
135
+ # rubocop:enable Metrics/CyclomaticComplexity
136
+
137
+ def dump_nil variant
138
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_NONE
139
+ end
140
+
141
+ # Based off protobuf for Python
142
+ INT32_MIN = -2147483648
143
+ INT32_MAX = 2147483647
144
+ INT64_MIN = -(1 << 63)
145
+ INT64_MAX = (1 << 63) - 1
146
+
147
+ def dump_numeric obj, variant, config
148
+ case obj
149
+ when true
150
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LONG
151
+ variant.long_value = 1
152
+ @estimated_pending_bytes += 2 # Header + short number
153
+ when false
154
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LONG
155
+ variant.long_value = 0
156
+ @estimated_pending_bytes += 2 # Header + short number
157
+ when Integer
158
+ dump_integer obj, variant
159
+ when Float
160
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_DOUBLE
161
+ variant.double_value = obj.to_f
162
+ @estimated_pending_bytes += 7 # Header + 64 bit float
163
+ when BigDecimal
164
+ dump_string obj.to_s, variant, config # TODO: NS: This might cut the decimal value, is that ok?
165
+ when Complex
166
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_COMPLEX
167
+ variant.complex_value = Com::Rookout::Variant::Complex.new real: obj.real.to_f,
168
+ imaginary: obj.imaginary.to_f
169
+ @estimated_pending_bytes += 8 # Large header + size + (header + 64 bit float) * 2
170
+ else
171
+ raise Exceptions::RookClassCannotBeSerialized.new(obj.class, "Unknown Numeric Type")
172
+ end
173
+ # TODO: ADD SUPPORT FOR RATIONALS
174
+ end
175
+
176
+ def dump_integer obj, variant
177
+ if obj > INT32_MIN && obj < INT64_MAX
178
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LONG
179
+ variant.long_value = obj
180
+ else
181
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LARGE_INT
182
+ variant.bytes_index_in_cache = get_string_index_in_cache obj.to_s
183
+ end
184
+ @estimated_pending_bytes += 3 # Header + number
185
+ end
186
+
187
+ def dump_string obj, variant, config
188
+ obj = obj.to_s
189
+ if obj.length > config.max_string
190
+ final_obj = obj[0...config.max_string]
191
+ else
192
+ final_obj = obj
193
+ end
194
+
195
+ variant.original_size = obj.length
196
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_STRING
197
+ variant.bytes_index_in_cache = get_string_index_in_cache final_obj
198
+ @estimated_pending_bytes += 6 # Header + number + header + number
199
+ end
200
+
201
+ def dump_time obj, variant
202
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_TIME
203
+ variant.time_value = Google::Protobuf::Timestamp.new
204
+ variant.time_value.from_time obj
205
+
206
+ @estimated_pending_bytes += 16 # Header + size + (header + 32 bit number + header + 64 bit number)
207
+ end
208
+
209
+ def dump_array obj, variant, current_depth, config, log_object_errors
210
+ variant.original_size = obj.length
211
+ @estimated_pending_bytes += 3 # Header + number
212
+
213
+ weighted_children_depth = current_depth + 1
214
+ if weighted_children_depth <= config.max_collection_depth
215
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LIST
216
+ obj.each_with_index do |value, index|
217
+ break if index >= config.max_width
218
+ variant.collection_values << dump_raw_object(value, weighted_children_depth, config, log_object_errors)
219
+ @estimated_pending_bytes += 3 # Header + size
220
+ end
221
+ else
222
+ dump_variant_type_max_depth variant, Com::Rookout::Variant::Type::VARIANT_LIST
223
+ end
224
+ end
225
+
226
+ def dump_hash obj, variant, current_depth, config, log_object_errors
227
+ variant.original_size = obj.length
228
+
229
+ weighted_children_depth = current_depth + 1
230
+ if current_depth <= config.max_collection_depth
231
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_MAP
232
+ obj.each_with_index do |(key, value), index|
233
+ break if index >= config.max_width
234
+ variant.collection_keys << dump_raw_object(key, weighted_children_depth, config, log_object_errors)
235
+ variant.collection_values << dump_raw_object(value, weighted_children_depth, config, log_object_errors)
236
+ @estimated_pending_bytes += 6 # Header + size + header + size
237
+ end
238
+ else
239
+ dump_variant_type_max_depth variant, Com::Rookout::Variant::Type::VARIANT_MAP
240
+ end
241
+ end
242
+
243
+ def dump_exception obj, variant, current_depth, config, log_object_errors
244
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_OBJECT
245
+ variant.attribute_names_in_cache << get_string_index_in_cache("message")
246
+ variant.attribute_values << dump_raw_object(obj.message, current_depth + 1, config, log_object_errors)
247
+ @estimated_pending_bytes += 6 # Header + number + header + size
248
+
249
+ variant.attribute_names_in_cache << get_string_index_in_cache("cause")
250
+ variant.attribute_values << dump_raw_object(obj.cause, current_depth + 1, config, log_object_errors)
251
+ @estimated_pending_bytes += 6 # Header + number + header + size
252
+
253
+ variant.attribute_names_in_cache << get_string_index_in_cache("backtrace")
254
+ variant.attribute_values << dump_raw_object(obj.backtrace, current_depth + 1, config, log_object_errors)
255
+ @estimated_pending_bytes += 6 # Header + number + header + size
256
+ end
257
+
258
+ def dump_code_object obj, variant
259
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_CODE_OBJECT
260
+
261
+ if obj.is_a?(Proc) || obj.is_a?(Method)
262
+ source_location = obj.source_location
263
+ else
264
+ source_location = [nil, nil]
265
+ end
266
+
267
+ if obj.is_a? Proc
268
+ name = ""
269
+ else
270
+ name = obj.name
271
+ end
272
+
273
+ variant.code_values << Com::Rookout::Variant::CodeObject.new(name: name,
274
+ filename: source_location[0],
275
+ lineno: source_location[1])
276
+ # NOTE: This size is probably less, in Python we use the optional fields of CodeObject and in Ruby we don't,
277
+ # but it is better to estimate more
278
+ @estimated_pending_bytes += 14 # Header + size + (header + number) * 4
279
+ end
280
+
281
+ def dump_user_class variant, obj, current_depth, config, log_object_errors
282
+ weighted_children_depth = current_depth + 1
283
+ if weighted_children_depth <= config.max_collection_depth
284
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_OBJECT
285
+
286
+ obj.instance_variables.each do |name|
287
+ raw_value = obj.instance_variable_get name
288
+ variant.attribute_names_in_cache << get_string_index_in_cache(name.to_s)
289
+ variant.attribute_values << dump_raw_object(raw_value, weighted_children_depth, config, log_object_errors)
290
+ @estimated_pending_bytes += 6 # Header + number + header + number
291
+ end
292
+ else
293
+ dump_variant_type_max_depth variant, Com::Rookout::Variant::Type::VARIANT_OBJECT
294
+ end
295
+ end
296
+
297
+ def dump_container_namespace namespace, log_errors
298
+ variant = Com::Rookout::Variant2.new
299
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_NAMESPACE
300
+
301
+ namespace.hash.each do |key, value|
302
+ variant.attribute_names_in_cache << get_string_index_in_cache(key.to_s)
303
+ variant.attribute_values << dump(value, log_errors)
304
+ end
305
+
306
+ @estimated_pending_bytes += 4 # One number (packed field), One header + length
307
+
308
+ variant
309
+ end
310
+
311
+ def dump_traceback_namespace namespace
312
+ variant = Com::Rookout::Variant2.new
313
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_TRACEBACK
314
+
315
+ namespace.depth.times do |i|
316
+ position = i + namespace.offset
317
+ break if position >= namespace.backtrace.length
318
+ frame = namespace.backtrace[position]
319
+
320
+ code_object = Com::Rookout::Variant::CodeObject.new filename: frame.source_location[0],
321
+ lineno: frame.source_location[1],
322
+ name: frame.eval("__method__").to_s
323
+ variant.code_values << code_object
324
+ # See dump_code_object
325
+ @estimated_pending_bytes += 14 # Header + size + (header + number) * 4
326
+ end
327
+ variant
328
+ end
329
+ end
330
+ end
331
+ end
@@ -8,11 +8,16 @@ module Rookout
8
8
 
9
9
  require_relative "../../protobuf/variant_pb"
10
10
 
11
+
11
12
  class ContainerNamespace < Namespace
12
13
  def initialize hash = {}
14
+ super()
13
15
  @hash = hash
14
16
  end
15
17
 
18
+ attr_reader :hash
19
+
20
+
16
21
  def call_method name, args
17
22
  return RubyObjectNamespace.new @hash.length if name == "size"
18
23
  super
@@ -8,6 +8,7 @@ module Rookout
8
8
 
9
9
  class FrameNamespace < Namespace
10
10
  def initialize binding
11
+ super()
11
12
  @binding = binding
12
13
  end
13
14
 
@@ -19,14 +20,12 @@ module Rookout
19
20
 
20
21
  def call_method name, args
21
22
  case name
22
- when "filename"
23
+ when "filename", "module"
23
24
  RubyObjectNamespace.new @binding.source_location[0]
24
25
  when "line"
25
26
  RubyObjectNamespace.new @binding.source_location[1]
26
27
  when "function"
27
28
  RubyObjectNamespace.new @binding.eval("__method__").to_s
28
- when "module"
29
- RubyObjectNamespace.new @binding.source_location[0]
30
29
  when "locals"
31
30
  locals args
32
31
  when "dump"
@@ -3,6 +3,7 @@ module Rookout
3
3
  module Namespaces
4
4
  class Namespace
5
5
  require_relative "../../exceptions"
6
+
6
7
  def call_method name, _args
7
8
  raise Exceptions::RookMethodNotFound.new(self.class.to_s, name)
8
9
  end
@@ -7,10 +7,6 @@ module Rookout
7
7
  require_relative "../../protobuf/variant_pb"
8
8
 
9
9
  class NoopNamespace < Namespace
10
- def initialize
11
- super
12
- end
13
-
14
10
  def call_method _name, _args
15
11
  Rookout::Processor::Namespaces::RubyObjectNamespace.new nil
16
12
  end
@@ -17,15 +17,18 @@ module Rookout
17
17
  @max_string = max_string
18
18
  end
19
19
 
20
- attr_reader :max_depth, :max_width, :max_collection_depth, :max_string
20
+ attr_reader :max_depth
21
+ attr_reader :max_width
22
+ attr_reader :max_collection_depth
23
+ attr_reader :max_string
21
24
  end
22
25
 
23
- OBJECT_DUMP_CONFIG_STRICT = ObjectDumpConfig.new 2, 10, 1, 128
24
- OBJECT_DUMP_CONFIG_DEFAULT = ObjectDumpConfig.new 4, 20, 2, 512
25
- OBJECT_DUMP_CONFIG_TOLERANT = ObjectDumpConfig.new 5, 50, 4, 4 * 1024
26
+ OBJECT_DUMP_CONFIG_STRICT = ObjectDumpConfig.new 2, 10, 2, 128
27
+ OBJECT_DUMP_CONFIG_DEFAULT = ObjectDumpConfig.new 4, 15, 4, 512
28
+ OBJECT_DUMP_CONFIG_TOLERANT = ObjectDumpConfig.new 5, 20, 5, 4 * 1024
26
29
 
27
30
  OBJECT_DUMP_CONFIG_STRING = ObjectDumpConfig.new 1, 0, 0, 64 * 1024
28
- OBJECT_DUMP_CONFIG_COLLECTION = ObjectDumpConfig.new 4, 100, 2, 512
31
+ OBJECT_DUMP_CONFIG_COLLECTION = ObjectDumpConfig.new 4, 100, 4, 512
29
32
 
30
33
  OBJECT_DUMP_TABLE = {
31
34
  "" => OBJECT_DUMP_CONFIG_DEFAULT,
@@ -37,17 +40,19 @@ module Rookout
37
40
  class RubyObjectNamespace < Namespace
38
41
  include RubyObjectSerializer
39
42
 
40
- def initialize obj, dump_config = OBJECT_DUMP_CONFIG_DEFAULT
43
+ def initialize obj, dump_config = nil
44
+ super()
41
45
  @obj = obj
42
- @dump_config = dump_config
46
+ @dump_config = dump_config || OBJECT_DUMP_CONFIG_DEFAULT
43
47
  end
44
48
 
45
- attr_reader :obj, :dump_config
49
+ attr_reader :obj
50
+ attr_reader :dump_config
46
51
 
47
52
  def tailor_limits!
48
53
  if @obj.is_a? String
49
54
  @dump_config = OBJECT_DUMP_CONFIG_STRING
50
- elsif @obj.is_a?(Hash) || @obj.is_a?(Array)
55
+ elsif (@obj.is_a?(Hash) || @obj.is_a?(Array)) && @obj.length > OBJECT_DUMP_CONFIG_TOLERANT.max_width
51
56
  @dump_config = OBJECT_DUMP_CONFIG_COLLECTION
52
57
  else
53
58
  @dump_config = OBJECT_DUMP_CONFIG_TOLERANT
@@ -62,20 +67,13 @@ module Rookout
62
67
  end
63
68
 
64
69
  def read_key key
65
- if @obj.is_a? Array
66
- key_int = key.to_i
67
- return RubyObjectNamespace.new @obj[key_int] if key_int >= 0 && key_int < @obj.length
68
- raise Exceptions::RookKeyNotFound, key
69
-
70
- elsif @obj.is_a? Hash
71
- return RubyObjectNamespace.new @obj[key] if @obj.key? key
72
- return RubyObjectNamespace.new @obj[key.to_sym] if key.is_a?(String) && @obj.key?(key.to_sym)
73
-
74
- @obj.each { |it, value| return RubyObjectNamespace.new value if it.to_s == key }
75
-
76
- raise Exceptions::RookKeyNotFound, key
70
+ case @obj
71
+ when Array, String
72
+ read_key_as_int key
73
+ when Hash
74
+ read_key_from_hash key
77
75
  else
78
- raise Exceptions::RookInvalidObjectForAccess.new(obj.class.to_s, "ReadKey")
76
+ raise Exceptions::RookInvalidObjectForAccess.new(@obj.class.to_s, "ReadKey")
79
77
  end
80
78
  end
81
79
 
@@ -93,6 +91,23 @@ module Rookout
93
91
  def dump log_object_errors
94
92
  dump_raw_object @obj, 0, @dump_config, log_object_errors
95
93
  end
94
+
95
+ private
96
+
97
+ def read_key_as_int key
98
+ key_int = key.to_i
99
+ return RubyObjectNamespace.new @obj[key_int] if key_int >= 0 && key_int < @obj.length
100
+ raise Exceptions::RookKeyNotFound, key
101
+ end
102
+
103
+ def read_key_from_hash key
104
+ return RubyObjectNamespace.new @obj[key] if @obj.key? key
105
+ return RubyObjectNamespace.new @obj[key.to_sym] if @obj.key? key.to_s.to_sym
106
+
107
+ @obj.each { |it, value| return RubyObjectNamespace.new value if it.to_s == key }
108
+
109
+ raise Exceptions::RookKeyNotFound, key
110
+ end
96
111
  end
97
112
  end
98
113
  end
@@ -24,6 +24,7 @@ module Rookout
24
24
 
25
25
  # rubocop:disable Metrics/PerceivedComplexity
26
26
  # rubocop:disable Metrics/CyclomaticComplexity
27
+ # rubocop:disable Style/ClassEqualityComparison
27
28
  def unsafe_dump_object obj, current_depth, config, log_object_errors
28
29
  variant = create_base_variant obj, current_depth, config, log_object_errors
29
30
 
@@ -49,7 +50,7 @@ module Rookout
49
50
 
50
51
  variant
51
52
  end
52
-
53
+ # rubocop:enable Style/ClassEqualityComparison
53
54
  # rubocop:enable Metrics/CyclomaticComplexity
54
55
  # rubocop:enable Metrics/PerceivedComplexity
55
56
 
@@ -83,23 +84,24 @@ module Rookout
83
84
  INT64_MAX = (1 << 63) - 1
84
85
 
85
86
  def dump_numeric obj, variant
86
- if obj == true
87
+ case obj
88
+ when true
87
89
  variant.variant_type = :VARIANT_INT
88
90
  variant.int_value = 1
89
- elsif obj == false
91
+ when false
90
92
  variant.variant_type = :VARIANT_INT
91
93
  variant.int_value = 0
92
- elsif obj.is_a? Integer
94
+ when Integer
93
95
  dump_integer obj, variant
94
- elsif obj.is_a? Float
96
+ when Float
95
97
  variant.variant_type = :VARIANT_DOUBLE
96
98
  variant.double_value = obj.to_f
97
- elsif obj.is_a? BigDecimal
99
+ when BigDecimal
98
100
  serialized_decimal = obj.to_s
99
101
  variant.variant_type = :VARIANT_STRING
100
102
  variant.string_value = Com::Rookout::Variant::String.new value: serialized_decimal,
101
103
  original_size: serialized_decimal.length
102
- elsif obj.is_a? Complex
104
+ when Complex
103
105
  variant.variant_type = :VARIANT_COMPLEX
104
106
  variant.complex_value = Com::Rookout::Variant::Complex.new real: obj.real.to_f,
105
107
  imaginary: obj.imaginary.to_f
@@ -9,10 +9,6 @@ module Rookout
9
9
  require_relative "ruby_object_namespace"
10
10
 
11
11
  class RubyUtilsNamespace < Namespace
12
- def initialize
13
- super
14
- end
15
-
16
12
  def call_method name, args
17
13
  case name
18
14
  when "exception"
@@ -7,6 +7,7 @@ module Rookout
7
7
 
8
8
  class StackNamespace < Namespace
9
9
  def initialize backtrace, offset = 0
10
+ super()
10
11
  @backtrace = backtrace
11
12
  @offset = offset
12
13
  end
@@ -8,11 +8,16 @@ module Rookout
8
8
 
9
9
  class TracebackNamespace < Namespace
10
10
  def initialize backtrace, offset, depth
11
+ super()
11
12
  @backtrace = backtrace
12
13
  @offset = offset
13
14
  @depth = depth
14
15
  end
15
16
 
17
+ attr_reader :backtrace
18
+ attr_reader :offset
19
+ attr_reader :depth
20
+
16
21
  def read_key key
17
22
  FrameNamespace.new @backtrace[key + @offset]
18
23
  end
@@ -11,6 +11,8 @@ module Rookout
11
11
 
12
12
  class SetOperation < Operation
13
13
  def initialize configuration, factory
14
+ super()
15
+
14
16
  @paths = []
15
17
 
16
18
  configuration["paths"].each do |key, value|
@@ -13,6 +13,8 @@ module Rookout
13
13
 
14
14
  class ArithmeticPath < Path
15
15
  def initialize path
16
+ super()
17
+
16
18
  if path.is_a? Hash
17
19
  path = path["path"] || path[:path]
18
20
  end
@@ -20,7 +22,7 @@ module Rookout
20
22
  @raw_path = path
21
23
 
22
24
  if path.start_with?("NOT(") && path.end_with?(")")
23
- @path = path["NOT(".length..-2]
25
+ @path = path[("NOT(".length)..-2]
24
26
  @negation = true
25
27
  else
26
28
  @path = path
@@ -33,7 +35,7 @@ module Rookout
33
35
  def read_from namespace
34
36
  begin
35
37
  result = Maps.parse @path, actions: Canopy::Actions.new(namespace)
36
- rescue Maps::ParseError => e
38
+ rescue Maps::ParseError, NameError => e
37
39
  raise RookInvalidArithmeticPath.new(@path, e)
38
40
  end
39
41
 
@@ -79,6 +79,8 @@ module Rookout
79
79
  end
80
80
 
81
81
  # rubocop:disable Metrics/AbcSize
82
+ # rubocop:disable Metrics/CyclomaticComplexity
83
+ # rubocop:disable Metrics/PerceivedComplexity
82
84
  def make_comp_exp _input, _start, _finish, elements
83
85
  # We can assume the following: atom ( opt_ atom )*
84
86
  # the first (which must be) will be simple atom
@@ -108,7 +110,7 @@ module Rookout
108
110
  flat_elements.each_with_index do |e, index|
109
111
  if e.is_a?(Opt) && e.level == level
110
112
  result = e.execute_operation flat_elements[index - 1], flat_elements[index + 1]
111
- flat_elements = flat_elements[0...index - 1] + [result] + flat_elements[index + 2..-1]
113
+ flat_elements = flat_elements[0...index - 1] + [result] + flat_elements[index + 2..]
112
114
  restart_scan = true
113
115
  break
114
116
  end
@@ -122,6 +124,8 @@ module Rookout
122
124
 
123
125
  flat_elements[0]
124
126
  end
127
+ # rubocop:enable Metrics/PerceivedComplexity
128
+ # rubocop:enable Metrics/CyclomaticComplexity
125
129
  # rubocop:enable Metrics/AbcSize
126
130
 
127
131
  def make_opt _input, _start, _finish, elements
@@ -50,9 +50,10 @@ module Rookout
50
50
  # If it's a dict, scan the keys, compensating for additional abstraction
51
51
  if b.is_a? Hash
52
52
  b.each_key do |key|
53
- if key.is_a? ObjectMarker
53
+ case key
54
+ when ObjectMarker
54
55
  return true if key.obj == a
55
- elsif key == a
56
+ when a
56
57
  return true
57
58
  end
58
59
  end
@@ -62,9 +63,10 @@ module Rookout
62
63
  # If it's an array, scan the value, compensating for additional abstraction
63
64
  if b.is_a? Array
64
65
  b.each do |value|
65
- if value.is_a? ObjectMarker
66
+ case value
67
+ when ObjectMarker
66
68
  return true if value.obj == a
67
- elsif value == a
69
+ when a
68
70
  return true
69
71
  end
70
72
  end