我最近回到了搁置一段时间的 Rails 副项目,目前正在升级各种组件,包括 Ruby 和 Rails。该应用程序在 Heroku 上运行,最近从 cedar-14 升级到 heroku-16 堆栈。我已经从 Rails 4.1.0 升级到 4.2.10(在推送到 Rails 5 之前需要提高测试覆盖率),从 Ruby 2.1.0 升级到 2.3.4-p301,大部分情况下运行良好。不幸的是,我看到了一些我无法理解的正则表达式行为。我在引用 ruby-doc.org对于预期的行为。
内容并不重要,但举个例子,假设我正在尝试解析 URL 并捕获协议(protocol),我一直使用以下代码来完成:
m = /(https?)/.match("https://www.example.com")
=> #<MatchData "https" 1:"https">
m[1]
=> "https"
当我在控制台中运行上面的代码时,这仍然按预期工作,无论是在我的本地开发机器上还是在 Heroku 上。但是在应用程序本身中,无论是在本地还是在 Heroku 上,第一条语句现在返回字符串“https”而不是 MatchData 对象,导致以下结果:
m = /(https?)/.match("https://www.example.com")
=> "https"
m[1]
=> "t"
在我的文档搜索和审查中,我找不到任何返回字符串而不是 MatchData 对象的场景。
当然,我可以只使用字符串,但由于显而易见的原因,这让我停顿了一下,因为我无法将其与文档协调一致。有没有人见过这个?也许一个更大的问题是——你能建议配置或其他因素,这些因素可能会导致我在 Rails C(预期行为)和 Rails S(意外行为)中看到不同的结果吗?如此简单的代码(不接触数据库等) ?
非常感谢您的帮助。
最佳答案
检查 match
方法是否被重新定义。例如,在一个干净的未修改的 irb
控制台中,我期望:
regex = /(https?)/
url_str = "https://www.example.com"
p regex.match(url_str)
p url_str.match(regex)
# => #<MatchData "https" 1:"https">
# should return nil, meaning it's defined in C and not in ruby code
p regex.method(:match).source_location
# reproduces your situation
class Regexp
alias_method :old_match, :match
def match(str)
old_match(str).to_s
end
end
p regex.match(url_str)
p url_str.match(regex)
# => "https"
# this should reveal if it was changed in a way similar to above
p regex.method(:match).source_location
关于ruby-on-rails - Ruby Regexp#match with capture 返回 String 而不是 MatchData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50893198/