class IDidMean::Processor

Attributes

error[R]
file[R]
number[R]
original_formatter[R]

Public Class Methods

new(error) click to toggle source
# File lib/i_did_mean/processor.rb, line 5
def initialize(error)
  @error = error

  return if backtrace.empty?

  @file, @number = backtrace.first.split(":").first(2)

  save_original_formatter
end

Public Instance Methods

call() click to toggle source
# File lib/i_did_mean/processor.rb, line 15
def call
  if should_process?
    replace_line(number)
    replace_formatter
  else
    restore_original_formatter
  end
end
should_process?() click to toggle source
# File lib/i_did_mean/processor.rb, line 24
def should_process?
  # Only process this error if:
  #   * error is present (**surprise, surprise**)
  #   * error was corrected (did_you_mean has done its magic)
  error&.respond_to?(:corrections) &&
    # * there is only one correction, so we can be certain to replace
    error.corrections.length == 1 &&
    # * this is not some internal backtrace (considering Rails here)
    backtrace.first
end

Private Instance Methods

backtrace() click to toggle source

Used for cleaning backtrace. We're only interested in application backtrace. This is Rails related.

# File lib/i_did_mean/processor.rb, line 79
def backtrace
  backtrace = error.backtrace
  backtrace = ::Rails.backtrace_cleaner.clean(backtrace) if defined?(::Rails)
  backtrace
end
corrected_method_name() click to toggle source
# File lib/i_did_mean/processor.rb, line 60
def corrected_method_name
  error.corrections
       .first
       .to_s
       .gsub(/\A:/, "")
       .gsub(/"/, "")
end
file_path() click to toggle source
# File lib/i_did_mean/processor.rb, line 68
def file_path
  @file_path ||= File.expand_path(file)
end
lines() click to toggle source
# File lib/i_did_mean/processor.rb, line 72
def lines
  @lines ||= IO.readlines(file_path)
end
original_formatter=(formatter) click to toggle source
# File lib/i_did_mean/processor.rb, line 102
def original_formatter=(formatter)
  @original_formatter ||= formatter
end
original_method_name() click to toggle source

Extracts method name from error message. Example:

For this error message:

  NameError: undefined local variable or method `foo' for #<Object:0x00007fab0c28a0f0>

It should return "foo".
# File lib/i_did_mean/processor.rb, line 51
def original_method_name
  case error
  when NameError
    error.name
  when KeyError
    error.key
  end
end
replace_formatter() click to toggle source
# File lib/i_did_mean/processor.rb, line 90
def replace_formatter
  DidYouMean.formatter = Formatter.new
end
replace_line(number) click to toggle source
# File lib/i_did_mean/processor.rb, line 85
def replace_line(number)
  lines[number.to_i - 1][original_method_name.to_s] = corrected_method_name
  IO.write(file_path, lines.join)
end
restore_original_formatter() click to toggle source
# File lib/i_did_mean/processor.rb, line 94
def restore_original_formatter
  DidYouMean.formatter = original_formatter
end
save_original_formatter() click to toggle source
# File lib/i_did_mean/processor.rb, line 98
def save_original_formatter
  self.original_formatter = DidYouMean.formatter
end