koheitakahashiのブログ

2020.07.01にプログラマーとして生を受けた私が学んだことや、日常について徒然に書いていきます。

Sendagaya.rb#308 参加レポート

はじめに

現在、参加させていただいているFJORD BOOT CAMPのスクラムのカリキュラムが難しくて、最近ブログを書くのを怠ってしまっていましたが、自分のようなエンジニアの卵は、「アウトプット無くして成長はない」と思い直し、久しぶりにブログを書こうと思った次第です🙇‍♂️

また、最近情報源についても気を使うようになり、「アウトプットしたい」と思う一方で、質の低いアウトプットをすることによって、ゴミ情報を増やしたくないなーと思ったことも、筆不精になった理由でした。

アウトプットの内容、質に気をつけていきたいところです💪

さて、今回はリモートで開催されたSendagaya.rb#308に参加し、そこで学んだことをまとめていきたいと思います。

sendagayarb.doorkeeper.jp

話題に挙がった内容

chompの挙動がおかしい?

こちらは、@sanfrece-osakaさんが挙げられた内容でした。

そもそも、.chompとは?

chomp(rs = $/) -> String

self の末尾から rs で指定する改行コードを取り除いた文字列を生成して返します。ただし、rs が "\n" ($/ のデフォルト値) のときは、実行環境によらず "\r", "\r\n", "\n" のすべてを改行コードとみなして取り除きます。

rs に nil を指定した場合、このメソッドは何もしません。 rs に空文字列 ("") を指定した場合は「パラグラフモード」になり、末尾の連続する改行コードをすべて取り除きます。

Ruby 2.7.0 リファレンスマニュアルより引用

文字列の末尾から改行コードを取り除いたものを返してくれるメソッドなんですね👀

さて、これのどこがおかしいのかということですが、以下をご覧ください。

# ①これは分かる
"hoge\r\n".chomp
#=> "hoge"

# ②これも分かる
"hoge\r\n".chomp ''
#=> "hoge"

# ③これも分かる
"hoge\n\r".chomp
#=> "hoge\n"

# ④ん??
"hoge\n\r".chomp ''
#=> "hoge\n\r"

# ⑤どういうこと??
"hoge\r".chomp ''
#=> "hoge\r"

公式リファレンスには、

rs に空文字列 ("") を指定した場合は「パラグラフモード」になり、末尾の連続する改行コードをすべて取り除きます。

と書いてあるのに、「④と⑤では、正常に動いてないのでは??」ということです。

これも教えていただいて、初めて知ったんですが、ruby/specというものがあるそうで、これはRubyに同梱されているテストなのですが、それを見てみると、以下のように書いてありました。

it "does not remove a final carriage return" do
  "abc\r".chomp!("").should be_nil
end

https://github.com/ruby/ruby/blob/master/spec/ruby/core/string/chomp_spec.rb より

つまり、上記のような挙動はRubyの想定内の挙動だということです。

\rが問題??

じゃあ、なぜこのような挙動になっているのかというと、問題の発端は\rにあるようでした。

\rの使われ方には、歴史があるようなのですが、\rとは、元々「carriage return」と呼ばれる制御文字で、「カーソルを文頭に戻すことを表す」もののようです。

故に、デフォルトでは、/rは便宜上改行文字として扱ってはいるけど、空文字を渡したときは、「carriage return」という本来の意味を汲み取って、あえて削除しないようにした、ということのようです(勉強会で出た結論がうろ覚えて自信がないですが・・・💦)。

感想

chompメソッドは、名前は知ってはいたけど、具体的にどういう処理をするものか分からなかったので、いい機会でした。 さらに、\n\rが本来は違うものなのだということも知らなかったので、一つ勉強になりました。

ruby/specの存在も知ることができましたし、有意義な時間でした😆

ありがとうございました🙇‍♂️🙇‍♂️