こんにちは。
泡アハです。
最近Rubyをメインに開発をしているのですが、
少しずつ型の弱い言語に慣れてきました。
とはいえ、やっぱり型が強い言語(C#やRustなど)が恋しい時がままありますw
先日、Rubyのコードで改行コードを"(ダブルコーテーション)でくくった場合と'(シングルコーテーション)でくくった場合で、
挙動が違うことを発見したので、本記事では深堀していきたいと思います。
結論
- シングルコーテーションでくくると、エスケープが必要な文字列が来た場合、自動でエスケープしてくれる
- 少なくともruby 3.2.2の場合
- そのため、.join('\n')とすると、"\n"として出力される
動作環境
$ ruby --version
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
何がおきたのか
まずはサンプルコードをご覧ください。
irb(main):001:0> ["a","b"].join("\n")
=> "a\nb"
irb(main):002:0> ["a","b"].join('\n')
=> "a\\nb"
ダブルコーテーションを用いて、.join("\n")とした場合と、シングルコーテーションを用いて.join('\n')した場合で出力が異なっています。
自分は、SlackAPIを実行するときに上記のようなjoinをしていたのですが、なぜか不要な\が入っていて、困りました。
ダブルコーテーションを使うことで不要な\がなくなることがわかったので、とりあえずその場は、""でくくることで事なきを得たのですが、
なぜなのか気になったので、調べてみました。
そもそもダブルコーテーションとシングルコーテーションの違いは?
それぞれの違いとしては、以下のように理解しています。
与えた文字列をそのまま文字列として、使用したい場合、シングルコーテーションを使う
式展開(#{})や、改行コードを標準出力時にそのまま使用したい場合は、ダブルコーテーションを使う
以下の記事を見る限りでも、概ね間違っていないように思います。
https://qiita.com/ryosuketter/items/ddad508cb0124e4fe378
SlackAPIを利用する場合は、ただの文字列として扱うべきと判断し、シングルコーテーションを使用していました。
ppしたら?
ppをした場合、どうなるのでしょうか?
.joinと同じように\がついています。
irb(main):003:0> pp "\n"
"\n"
=> "\n"
irb(main):004:0> pp '\n'
"\\n"
=> "\\n"
%qしたら?
%qは、%q[]内に記載した文字列を自動でエスケープしてくれる記法です。
%qも同様に改行コードをエスケープしてくれるようです。
irb(main):007:0> %q[hello\nruby]
=> "hello\\nruby"
シングルコーテーションの中にダブルコーテーションを使ったら?
ここまでの実験を元に仮説として、シングルコーテーションは、文字列を文字列として扱うためにエスケープ文字を自動でエスケープするのでは?と考えました。
であれば、改行コード以外のエスケープ文字をシングルコーテーションに含んだらどうなるのか。
試してみます。
irb(main):001:0> 'hello"ruby'
=> "hello\"ruby"
想定通り、ダブルコーテーションがエスケープされて出力されました。
まとめ
ここまでの結果を踏まえて、
不要な\というのは、シングルコーテーションが\nをエスケープしたから
ということがわかりました。
SlackAPIで改行を使いたい場合、シングルコーテーションは使わず、ダブルコーテーションを使う必要がありそうです。
コメント