Skip to content

Commit fcbde0d

Browse files
authored
Merge pull request #1599 from Shopify/uk-fix-ruby-head
Fix evals with automatic source location in Ruby 3.3
2 parents f8eefe2 + d82f3ff commit fcbde0d

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

lib/tapioca/gem/pipeline.rb

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,27 @@ def symbol_in_payload?(symbol_name)
110110
@payload_symbols.include?(symbol_name)
111111
end
112112

113+
# this looks something like:
114+
# "(eval at /path/to/file.rb:123)"
115+
# and we are just interested in the "/path/to/file.rb" part
116+
EVAL_SOURCE_FILE_PATTERN = T.let(/\(eval at (.+):\d+\)/, Regexp)
117+
113118
sig { params(name: T.any(String, Symbol)).returns(T::Boolean) }
114119
def constant_in_gem?(name)
115120
return true unless Object.respond_to?(:const_source_location)
116121

117-
source_location, _ = Object.const_source_location(name)
118-
return true unless source_location
122+
source_file, _ = Object.const_source_location(name)
123+
return true unless source_file
119124
# If the source location of the constant is "(eval)", all bets are off.
120-
return true if source_location == "(eval)"
125+
return true if source_file == "(eval)"
126+
127+
# Ruby 3.3 adds automatic definition of source location for evals if
128+
# `file` and `line` arguments are not provided. This results in the source
129+
# file being something like `(eval at /path/to/file.rb:123)`. We try to parse
130+
# this string to get the actual source file.
131+
source_file = source_file.sub(EVAL_SOURCE_FILE_PATTERN, "\\1")
121132

122-
gem.contains_path?(source_location)
133+
gem.contains_path?(source_file)
123134
end
124135

125136
sig { params(method: UnboundMethod).returns(T::Boolean) }

0 commit comments

Comments
 (0)