class TappingDevice::Trackers::MutationTracker
Public Class Methods
new(options, &block)
click to toggle source
Calls superclass method
TappingDevice::new
# File lib/tapping_device/trackers/mutation_tracker.rb, line 4 def initialize(options, &block) options[:hijack_attr_methods] = true super @snapshot_stack = [] end
Public Instance Methods
stop!()
click to toggle source
Calls superclass method
TappingDevice#stop!
# File lib/tapping_device/trackers/mutation_tracker.rb, line 16 def stop! super @ivar_snapshot_trace_point.disable end
track(object)
click to toggle source
Calls superclass method
TappingDevice#track
# File lib/tapping_device/trackers/mutation_tracker.rb, line 10 def track(object) super insert_snapshot_taking_trace_point self end
Private Instance Methods
build_payload(tp:, filepath:, line_number:)
click to toggle source
Calls superclass method
TappingDevice#build_payload
# File lib/tapping_device/trackers/mutation_tracker.rb, line 46 def build_payload(tp:, filepath:, line_number:) payload = super if change_capturing_event?(tp) payload.ivar_changes = capture_ivar_changes end payload end
capture_ivar_changes()
click to toggle source
# File lib/tapping_device/trackers/mutation_tracker.rb, line 56 def capture_ivar_changes changes = {} additional_keys = @latest_instance_variables.keys - @instance_variables_snapshot.keys additional_keys.each do |key| changes[key] = {before: Output::PayloadWrapper::UNDEFINED, after: @latest_instance_variables[key]} end removed_keys = @instance_variables_snapshot.keys - @latest_instance_variables.keys removed_keys.each do |key| changes[key] = {before: @instance_variables_snapshot[key], after: Output::PayloadWrapper::UNDEFINED} end remained_keys = @latest_instance_variables.keys - additional_keys remained_keys.each do |key| next if @latest_instance_variables[key] == @instance_variables_snapshot[key] changes[key] = {before: @instance_variables_snapshot[key], after: @latest_instance_variables[key]} end changes end
change_capturing_event?(tp)
click to toggle source
# File lib/tapping_device/trackers/mutation_tracker.rb, line 91 def change_capturing_event?(tp) !snapshot_capturing_event?(tp) end
filter_condition_satisfied?(tp)
click to toggle source
# File lib/tapping_device/trackers/mutation_tracker.rb, line 33 def filter_condition_satisfied?(tp) return false unless is_from_target?(tp) if snapshot_capturing_event?(tp) true else @latest_instance_variables = target_instance_variables @instance_variables_snapshot = @snapshot_stack.pop @latest_instance_variables != @instance_variables_snapshot end end
insert_snapshot_taking_trace_point()
click to toggle source
we need to snapshot instance variables at the beginning of every method call so we can get a correct state for the later comparison
# File lib/tapping_device/trackers/mutation_tracker.rb, line 25 def insert_snapshot_taking_trace_point @ivar_snapshot_trace_point = build_minimum_trace_point(event_type: :call) do snapshot_instance_variables end @ivar_snapshot_trace_point.enable unless TappingDevice.suspend_new end
print_snapshot_stack(tp)
click to toggle source
belows are debugging helpers I'll leave them for a while in case there's a bug in the tracker
# File lib/tapping_device/trackers/mutation_tracker.rb, line 97 def print_snapshot_stack(tp) puts("===== STACK - #{tp.callee_id} (#{tp.event}) =====") puts(@snapshot_stack) puts("================ END STACK =================") end
print_state_comparison()
click to toggle source
# File lib/tapping_device/trackers/mutation_tracker.rb, line 103 def print_state_comparison puts("###############") puts(@latest_instance_variables) puts(@instance_variables_snapshot) puts("###############") end
snapshot_capturing_event?(tp)
click to toggle source
# File lib/tapping_device/trackers/mutation_tracker.rb, line 87 def snapshot_capturing_event?(tp) tp.event == :call end
snapshot_instance_variables()
click to toggle source
# File lib/tapping_device/trackers/mutation_tracker.rb, line 77 def snapshot_instance_variables @snapshot_stack.push(target_instance_variables) end
target_instance_variables()
click to toggle source
# File lib/tapping_device/trackers/mutation_tracker.rb, line 81 def target_instance_variables target.instance_variables.each_with_object({}) do |ivar, hash| hash[ivar] = target.instance_variable_get(ivar) end end