Ruby 的 heredoc

最近读到这样一段代码,

@stats = ParticipantStat.where(round: @rounds, round_stat: %w(win draw loss)).group('participant_id')
  .select(
    <<-EOT
      participant_id,
      COUNT(round_id) as round_count,
      SUM(CASE WHEN round_stat IN (1) THEN 1 ELSE 0 END) as winning_round_count,
      SUM(CASE WHEN mvp THEN 1 ELSE 0 END) as total_mvp,
      SUM(point) AS total_point,
      SUM(rebound) AS total_rebound,
      SUM(assist) AS total_assist,
      SUM(score) AS total_score
    EOT
      ).order('total_score desc, total_point desc, total_rebound desc, total_assist desc, total_mvp desc').includes(participant: :profile)

大概能猜出是什么意思。但这个 EOT 是什么鬼?翻遍了 google,也没找到靠谱的解释。就只好去问同事。

同事看了一眼,甩给了我一个链接……

这是 Ruby 的一个方法,叫 heredoc,作用很简单,就是实现多行字符串,真正目的其实是让代码读起来更加方便。这个方法坑人的地方在于,EOT 不是方法关键字,真正调用方法的是 <<-,而这里的 EOT 可是任意的字符!

例如这个例子

puts <<-ANY_WORD
  hello wolrd!
  hello wolrd!
ANY_WORD

运行结果是

  hello wolrd!
  hello wolrd!

注意这里,如果源码前面带了缩进(为了阅读方便),输出的结果也会有缩进。在 Ruby 2.3 中新增了一个功能解决了这个功能,改用 <<~ 方法就可以消除结果的的缩进。

· rails, Ruby