如何在`gsub`和`match`中避免Ruby Perlisms?

时间:2015-12-22 02:12:51

标签: ruby regex coding-style global-variables

我想避开我的方法:

def page_cover
  return cover_title unless cover_title.match(/#{ capitalised_acronyms }/).present?
  cover_title.gsub(/#{ capitalised_acronyms }/, $&.upcase)
end

因为它看起来像Perly,我听说a news它可能在将来被弃用。从书中可以看出:

  1. 首选String#matchString#=~。前者返回MatchData对象中的所有匹配信息,而不是几个特殊的全局变量。
  2. 使用较长的,更具描述性的全局变量别名而不是其简短的神秘名称(例如,$LOAD_PATH而不是$:)。大多数较长的名称仅在加载英语库后才可用。
  3. 避免隐式读取或写入$_全局变量的方法(例如Kernel#printRegexp#~等)。
  4. 我认为我违反了#3:

    $&.upcase
    

    欢迎任何建议。

1 个答案:

答案 0 :(得分:1)

虽然我既不同意也不反对避免" Perlisms的一般原则,"我同意避免使用$ +标点符号变量是提高代码可读性的好方法。

$&没有就地替代(持有最后一个正则表达式匹配)。但是,您可以使用MatchData返回的String#match对象访问匹配的字符串。

def page_cover
  if matchdata = cover_title.match(/#{capitalised_acronyms}/)
    cover_title.gsub(/#{capitalised_acronyms}/, matchdata[0].upcase)        
  else
    cover_title
  end
end

注意

如上所述,此方法(如您的示例方法)将使用大写版本的 替换所有匹配的小写首字母缩略词匹配的第一个首字母缩写词:ie "I love the nfl and nba"变为"I love the NFL and NFL" 。如果这是无意的,那么有一种更简单的方法来编写这种方法:

def page_cover
  cover_title.gsub(/#{capitalised_acronyms}/, &:upcase)
end

这会使用&运算符(与$&完全无关)将符号:upcase转换为幕后的{|x| x.upcase }块。