class AddedMethods::AddedMethod

Attributes

base[RW]
def[RW]
file[RW]
klass[RW]
line[RW]
name[RW]
singleton[RW]
singleton?[RW]
time[RW]

Public Class Methods

new(args = {}) click to toggle source
# File lib/added_methods/added_method.rb, line 33
def initialize(args = {})
  self.time = Time.now

  args.each { |key, value|
    send("#{key}=", value)
  }
end

Public Instance Methods

[](key) click to toggle source
# File lib/added_methods/added_method.rb, line 44
def [](key)
  send(key.to_sym == :class ? :klass : key)
end
extract_source(num_lines = nil) click to toggle source
# File lib/added_methods/added_method.rb, line 56
def extract_source(num_lines = nil)
  lines = extract_source_from_script_lines(num_lines)

  # try to make sure we correctly extracted the method
  # definition, otherwise try to get it from Ruby2Ruby
  if lines && lines.first =~ /\b#{name}\b/
    lines
  else
    extract_source_from_r2r || lines
  end
end
r2r_source() click to toggle source
# File lib/added_methods/added_method.rb, line 52
def r2r_source
  @r2r_source ||= extract_source_from_r2r
end
source() click to toggle source
# File lib/added_methods/added_method.rb, line 48
def source
  @source ||= extract_source
end
to_s() click to toggle source
# File lib/added_methods/added_method.rb, line 68
def to_s
  str = "# File #{file}, line #{line}"

  case lines = source
    when Array
      num   = line - 1
      width = (num + lines.size).to_s.length

      lines.map! { |l| "%0#{width}d: %s" % [num += 1, l] }

      "#{' ' * width}  #{str}\n#{lines}"
    when String
      "#{str}#{lines}"
    else
      str
  end
end

Private Instance Methods

extract_source_from_r2r() click to toggle source

Use Ruby2Ruby as a last resort. But note that it only ever finds the latest, i.e. currently active, method definition, not necessarily the one we're looking for.

# File lib/added_methods/added_method.rb, line 134
def extract_source_from_r2r
  if Object.const_defined?(:Ruby2Ruby)
    " [R2R]\n#{Ruby2Ruby.translate(klass, name)}"
  end
end
extract_source_from_script_lines(num_lines = nil) click to toggle source
# File lib/added_methods/added_method.rb, line 88
def extract_source_from_script_lines(num_lines = nil)
  return unless Object.const_defined?(:SCRIPT_LINES__)
  return unless script_lines = SCRIPT_LINES__[file]

  start, from, to = line - 1, line, script_lines.size - 1

  # suppose we're already in a block
  in_block = 1

  num_lines ||= case definition = script_lines[start]
    # def ... end, or do ... end style block
    when /\b(?:def|do)\b/
      definition =~ /\bend\b/ ? 1 : begin
        from.upto(to) { |i|
          case line = script_lines[i]
            when /[^;\s]\s+(?:if|unless)\b/
              # probably postfix conditional, ignore
            when /\b(?:if|unless|while|until|def|do)\b/
              in_block += 1
            when /\bend\b/
              in_block -= 1
          end

          break i - start + 1 if in_block.zero?
        }
      end
    # { ... } style block
    when /\bdefine_method\b/
      from.upto(to) { |i|
        line = script_lines[i]

        in_block += line.count('{')
        in_block -= line.count('}')

        break i - start + 1 if in_block.zero?
      }
    else
      1
  end

  script_lines[start, num_lines]
end