【问题标题】:How can I avoid Ruby Perlisms in `gsub` and `match`?如何避免 `gsub` 和 `match` 中的 Ruby Perlisms?
【发布时间】:2015-12-22 02:12:50
【问题描述】:

我想避免我的方法:

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#match 而不是String#=~。前者在MatchData 对象中返回所有匹配信息,而不是几个特殊的全局变量。
  2. 使用更长、更具描述性的全局变量别名,而不是它们的简短隐秘名称(例如,$LOAD_PATH 而不是 $:)。大多数较长的名称只有在加载英文库后才可用。
  3. 避免隐式读取或写入 $_ 全局变量(例如,Kernel#printRegexp#~ 等)的方法。

我认为我在以下方面违反了#3:

$&.upcase

欢迎提出任何建议。

【问题讨论】:

  • 您的问题是什么?您是否应该遵循您引用的文章中的建议?您的问题实际上与 Perl 没有任何关系。对 Ruby 发展的影响是多方面的。如果您想知道对语言的发展方向做出某些假设是否明智,那么我们如何到达现在的位置并不重要。请记住,Ruby 僧侣在更改语言时非常小心。他们最不想要的就是修道院外的愤怒暴徒。
  • 我试图将您的方法编辑为一个更简单的示例案例,但后来我意识到我改变了含义。你知道$& 只被评估一次,不管gsub 在字符串中遇到多少匹配?如果您使用cover_title = "I love the nfl and nba"capitalised_acronyms = "nba|nfl|mlb",您的方法将返回"I love the NFL and NFL"。这似乎是一个错误。
  • 你有没有决定在这里做什么?

标签: ruby regex coding-style global-variables


【解决方案1】:

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

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

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

注意

如所写,此方法(如您的示例方法)会将所有匹配的小写首字母缩写词替换为匹配的第一个首字母缩写词的大写版本:即 "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 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    相关资源
    最近更新 更多