ruby は改行がどうなるのかが大変わかりにくい。
まあ、こうなるだろうと想像できる感じに書くと想像通りになるので普通は困らないんだけど、微妙なケースが結構あって、そういうときにはほんとうに全然わからない。
微妙だな、と思わないように書けばいいんだけど、他人のソースに微妙なパターンがあるとドキドキする。
私自身はほとんど利用したことがないけど、ruby にはバックスラッシュによる行継続がある。
あるんだけど、C/C++ の行継続とは異なり、文脈によって行継続したりしなかったりする。
というわけで、いろいろ試した。
全て、ruby 2.1.3p242 での動作結果。
+ による結合
p(3+4) #=> 7 ※ 当たり前
p(3+
4) #=> 7 ※ ここで改行してもよい
p(3
+4)#=> エラー。なんでだかわからない。p(3;+4) で 4 が出ると思ってた。
p((3
+4))#=> 4 ※ これは p(3;+4) と解釈されて 4。なんでだろ。
p(3\
+4)#=> 7 ※ バックスラッシュを行末に入れると行継続になり、p(3+4) になる。
p(3
.+4)#=> 7 ※ ピリオドを付けるとバックスラッシュなしでも行継続になる。
p(3+(4+
5))#=> 12 ※ ふつう。
p(3+(4
+5))#=> 8 ※ これはエラーにならないけど、p(3+(4;+5)) と解釈されて、 8 になる。
p(3+(4 \
+5))#=> 12 ※ バックスラッシュを行末に入れると行継続になり、p(3+(4+5)) になる。
コメントの処理
p(3+(4+
#comment
5))#=> 12 ※ コメントをはさんでも良い。
p(3+(4+
#comment \
5))#=> 12 ※ コメントの末尾のバックスラッシュは行継続にならない
文字列とシンボル
p "ab" #=> "ab" ※ 当たり前
p "a\
b" #=> "ab" ※ 文字列中の行継続。改行はなかったことになる。
p "a\
b" #=> "a \nb" ※ Qiita 上では見えないけど、バックスラッシュの後に空白があるのでこうなる。怖い。
p :ab #=> :ab ※ 当たり前
p :a\
b #=> エラー。シンボルの途中では、バックスラッシュをはさんでも改行できない。
p :"ab" #=>:ab ※ 当たり前
p :"a\
b" #=>:ab ※ "" でくくっておくと、バックスラッシュで行継続になる
数値リテラル
p 123 #=> 123 ※ 当たり前
p 12\
3 #=> エラー。数値リテラルの途中も改行できない。
p 12e+3 #=> 12000.0 ※ 当たり前
p 12e+\
3 #=> 浮動小数点リテラルの途中だと、バックスラッシュをはさんでも改行できない。
Hashリテラル
p( { a:1 } )#=> {:a=>1} ※ 当たり前
p( { a:
1 } )#=> {:a=>1} ※ ここに改行を入れても良い。
p( { a :1 } )#=>エラー。 シンボル名とコロンの間は空白すら入れられない
p( { a
:1 } )#=> {:a=>1} ※ エラー。空白がダメなので、当然改行もエラー
p( { a\
:1 } )#=> {:a=>1} ※ エラー。バックスラッシュを入れてもダメ
ピリオド
p 1.abs #=>1 ※ 当たり前
p 1.
abs #=>1 ※ + と同様、ここで改行できる。
p 1
.abs #=>1 ※ ピリオドの場合は、ピリオドの前でも改行できる。
配列演算
p "abc"[0] #=> "a" ※ 当たり前
p "abc"
[0] #=> "abc" ※ 「p "abc" で "abc" が出て、[0] は無駄な配列定義になる
p "abc"\
[0] #=> "a" ※ バックスラッシュで行継続になる。
メソッド呼び出し
def hoge(x);p "hoge:#{x}";end
def fuga(x="!");p "fuga:#{x}";end
hoge(1) #=> "hoge:1" ※ 当たり前
fuga(1) #=> "fuga:1" ※ 当たり前
hoge
(1) #=> エラー
fuga
(1) #=> fuga の行で "fuga!" が出力され、(1) には効果がない。
hoge(
1) #=> "hoge:1" ※ ここに改行を入れても良い。
hoge\
(1) #=> バックスラッシュを入れると行継続できる。
ho\
ge(1) #=> ここにはバックスラッシュを入れても改行できない。
hoge 1 #=>"hoge:1" ※ 当たり前
hoge
1 # エラー
hoge\
1 # => "hoge:1" ※ バックスラッシュで行継続になる。
lambda
pr=->(x){ p "lambda:#{x}" }
pr.(2) #=> "lambda:2" ※ 当たり前
pr.
(2) #=> "lambda:2" ※ ピリオドの後の改行は OK。
pr
.(2) #=> "lambda:2" ※ ピリオドの前でも OK。
pr=->(x)
{ p "lambda:#{x}" } #=> エラー。結構厳しいね。
pr=->
(x){ p "lambda:#{x}" } #=> エラー。ここの改行もダメ。
pr=->(x)\
{ p "lambda:#{x}" } #=> バックスラッシュを入れるとOK。
pr=->\
(x){ p "lambda:#{x}" } #=> バックスラッシュを入れるとOK。
% 記法
p %Q(foo) #=> "foo" ※ 当たり前
p %Q(f
oo) #=> "f\noo" ※ 改行すると改行が入る。当たり前
p %Q(f\
oo) #=> "foo" ※ バックスラッシュで行継続となり、改行はなかったことになる。
p %q(f\
oo) #=> "f\\\noo" ※ バックスラッシュはバックスラッシュそのものとなる。
p %w( foo ) #=> ["foo"] ※ 当たり前
p %w( f\
oo ) #=> ["f\noo"] ※ "f" と "oo" にはならないが、文字列リテラルと異なり、改行が入る。
p %W( f\
oo ) #=> ["f\noo"] ※ %w と %W で同じ動作になる。
p %i(foo) #=>[:foo] ※ 当たり前。
p %i(f\
oo) #=>[:"f\noo"] ※ %w と同じ動作
p %s(foo) #=>:foo ※ 当たり前。
p %s(f
oo) #=>:"f\noo" ※ 改行してもよい。
p %s(f\
oo) #=>:"f\\\noo" ※ バックスラッシュは行継続にならず、シンボルの一部になる。
その他にも
その他にも、後置 if とか、ブロック引数とか、case〜when とか、気になることはたくさんあるけど、取り敢えず今日のところはこれぐらいで。