うぇぶろぐ

ずっと貧乏暇なし

Active Support の String#remove, String#squish, String#truncate のコードリーディングをする

今回は Active Support の core_ext の String拡張である remove, squish, truncate メソッドのコードリーディングをしたのでまとめておきます。

remove

引数に該当するパターンが全て削除される

また remove! という破壊的メソッドも用意されており、 それぞれ違いは、レシーバそのものが上書きされるか、レシーバをコピーした値を処理して返されるかである

str = "string"
puts str.remove("i") # => "strng"

https://github.com/rails/rails/blob/5-2-2/activesupport/lib/active_support/core_ext/string/filters.rb#L32

処理の流れ

  1. レシーバのコピーを作成し、remove! で処理する
  2. patterns をそれぞれ gsub メソッドでパターンにマッチした文字列を置換して返す

squish

行頭、行末のホワイトスペースを削除し、連続するホワイトスペースを1つにする

squish も同じく破壊的メソッド squish! が用意されている

str = "\sstr\s\s\sing\s"
new_str = str.squish

puts str # => "str   ing"
puts new_str # => "str ing"

https://github.com/rails/rails/blob/5-2-2/activesupport/lib/active_support/core_ext/string/filters.rb#L21

処理の流れ

  1. remove メソッドと同様で、レシーバのコピーを作成し squish! で処理する
  2. squish! では gsub メソッドで連続したホワイトスペースを1つに置換し、strip! メソッドで行頭と行末を trim した文字列を返す

truncate

引数の文字数( length )までレシーバの文字列を切り詰めたコピーを返す

str1 = "string string string"
new_str1 = str1.truncate(6)

puts str1 # => "string string string"
puts new_str1 # => "str..."

new_str2 = str1.truncate(12, separator: " ")

puts new_str2 # => "string..."

https://github.com/rails/rails/blob/5-2-2/activesupport/lib/active_support/core_ext/string/filters.rb#L66

オプションについて

  • omission
    省略文字としてデフォルトでは ... が語尾に付けられるが、omission を指定することでカスタムすることができる
    また ... は文字数としてカウントされる
  • separator
    separator を指定された文字列で区切ることで自然にレシーバを区切ることができる
    separator には正規表現を使うこともできる

処理の流れ

  1. 引数の文字数( length )よりレシーバの文字数が少なければ、そのままレシーバが返される
  2. omission を含めた文字数 = length_with_room_for_omission を算出する
  3. separator が指定されていれば、rindexメソッドで 対象の separtor の位置を探索した値を使う
    指定がなければ、length_with_room_for_omission を使う
  4. 最後に length_with_room_for_omission まで切り取ったレシーバの文字列と omission を結合して返される

まとめ

Integer の拡張に続いて String の拡張メソッドを抜粋して読んでみましたが、
こちらもすごくシンプルで「読める!読めるぞ!」って感じでスラスラと読めました。
引き続き、残りのメソッドや別の Class の拡張メソッドを読んだりしたいと思います。