lib/tapioca/runtime/source_location.rb
# typed: true # frozen_string_literal: true module Tapioca module Runtime class SourceLocation # this looks something like: # "(eval at /path/to/file.rb:123)" # and we are interested in the "/path/to/file.rb" and "123" parts EVAL_SOURCE_FILE_PATTERN = /^\(eval at (?<file>.+):(?<line>\d+)\)/ #: Regexp #: String attr_reader :file #: Integer attr_reader :line def initialize(file:, line:) # Ruby 3.3 adds automatic definition of source location for evals if # `file` and `line` arguments are not provided. This results in the source # file being something like `(eval at /path/to/file.rb:123)`. We try to parse # this string to get the actual source file. eval_pattern_match = EVAL_SOURCE_FILE_PATTERN.match(file) if eval_pattern_match file = eval_pattern_match[:file] line = eval_pattern_match[:line].to_i end @file = file @line = line end # force all callers to use the from_loc method private_class_method :new class << self #: ([String?, Integer?]? loc) -> SourceLocation? def from_loc(loc) new(file: loc.first, line: loc.last) if loc&.first && loc.last end end end end end