class ProductionBreakpoints::Breakpoints::Base

Constants

TRACEPOINT_TYPES

Attributes

name[R]
provider_name[R]
tracepoint[R]

Public Class Methods

new(source_file, start_line, end_line, trace_id: 1) click to toggle source
# File lib/ruby-production-breakpoints/breakpoints/base.rb, line 13
def initialize(source_file, start_line, end_line, trace_id: 1)
  @injector_module = nil
  @source_file = source_file
  @start_line = start_line
  @end_line = end_line
  @trace_id = trace_id
  @method = self.class.name.split('::').last.downcase
  @parser = ProductionBreakpoints::Parser.new(@source_file)
  @node = @parser.find_definition_node(@start_line, @end_line)
  @method_override = ProductionBreakpoints::MethodOverride.new(@parser, start_line, end_line)
  @ns = Object.const_get(@parser.find_definition_namespace(@node)) # FIXME: error handling, if not found
  @provider_name = File.basename(@source_file).gsub('.', '_')
  @name = "#{@method}_#{@trace_id}"
  @tracepoint = StaticTracing::Tracepoint.new(@provider_name, @name, *self.class.const_get('TRACEPOINT_TYPES'))
end

Public Instance Methods

handle(caller_binding) click to toggle source

Allows for specific handling of the selected lines

# File lib/ruby-production-breakpoints/breakpoints/base.rb, line 49
def handle(caller_binding)
  eval(@method_override.handler_src.join, caller_binding)
end
install() click to toggle source
# File lib/ruby-production-breakpoints/breakpoints/base.rb, line 29
def install
  @injector_module = build_redefined_definition_module(@node)
  @ns.prepend(@injector_module)
end
load() click to toggle source
# File lib/ruby-production-breakpoints/breakpoints/base.rb, line 40
def load
  @tracepoint.provider.enable
end
resume(caller_binding) click to toggle source
# File lib/ruby-production-breakpoints/breakpoints/base.rb, line 53
def resume(caller_binding)
  eval(@method_override.resume_src.join, caller_binding) if @method_override.resume_src
end
uninstall() click to toggle source

FIXME: saftey if already uninstalled

# File lib/ruby-production-breakpoints/breakpoints/base.rb, line 35
def uninstall
  @ns.instance_eval { unprepend(@injector_module) }
  @injector_module = nil
end
unload() click to toggle source
# File lib/ruby-production-breakpoints/breakpoints/base.rb, line 44
def unload
  @tracepoint.provider.disable
end

Private Instance Methods

build_redefined_definition_module(node) click to toggle source

A custom module we'll prepend in order to override us to keep the expected binding for the wrapped code, and remainder of the method

# File lib/ruby-production-breakpoints/breakpoints/base.rb, line 61
def build_redefined_definition_module(node)
  # This is the metaprogramming to inject our breakpoint handle
  puts "Trace ID: #{@trace_id}"
  puts "keys #{ProductionBreakpoints.installed_breakpoints.keys.inspect}"
  handler = "ProductionBreakpoints.installed_breakpoints[\"#{@trace_id}\"].handle(Kernel.binding)"

  # This injects our handler at the end of the original source code
  injected = @parser.inject_metaprogramming_handlers(handler, node.first_lineno, node.last_lineno)
  # ProductionBreakpoints.config.logger.debug(injected)
  Module.new { module_eval { eval(injected); eval('def production_breakpoint_enabled?; true; end;') } }
end