Ruby Regexp#与capture匹配返回String而不是MatchData

时间:2018-06-17 02:23:38

标签: ruby-on-rails ruby regex rails-console

我最近回到了一个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并捕获协议,我总是用以下代码完成:

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(意外行为)上看到不同的结果在这样简单的代码上(不接触数据库等) ?

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:0)

检查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