Ruby Advent Calendar 2018の 2 日目です。
「何かすごいテクいことを書かなくちゃ!」と気負っていたのですが、もともと Advent Calendar は「5分で書けるようなTipsをやりとりするイベント」として行われていたらしいので、これにあやかってハードルを下げることに従事したいと思います。
きっかけ
もともと C や Java を使う仕事に就いていたのですが、転職を機に Ruby を触るようになって早数年。未だにコードレビューで指摘される個人的に忘れがちな Ruby イディオムを Tips として残そうと思いました。
個人的によく指摘をうけるイディオム
||=
nil チェックと代入を一緒にやってくれる操作。
x ||= 1
自分はよくこう書いてしまいます。
x = 1 if x.nil?
この後置 if も慣れない人にはこう書くと分かりやすいかと思います。
if x.nil?
x = 1
end
x ||= 1
は x || (x = 1)
と同義なのですが、nil チェックを明示的に書く癖が未だに抜けません。毎度毎度「Ruby っぽくないなぁ〜」というような指摘を受けます。
File.open
ファイルの読み書きをする際の操作。
File.open(filepath, 'w') do |f|
f.write("hoge")
end
こう書いてしまう場合があります。
f = File.open(filepath, 'w')
f.write("hoge")
f.close
malloc/free 同様、メモリー領域を確保したら最後に解放しなければならないのは当然なのですが、ブロックを使えば明示的に close
しなくても解放してくれますよ、というもの。主にコピペしたコードの自己レビューで見落としてしまうことが多いです。
private の適用範囲
「private を宣言したクラス内のみで利用可能」と勘違いする Java 脳です。
実際には継承先にも使うことは可能です。ただし、クラスメソッドの場合は同一クラスでも private なインスタンスメソッドを呼び出すことが出来ません(レシーバー経由での private メソッドアクセスが言語仕様として認められていないため)。
これもついつい「継承先で使うから」と public に定義し、後々「private でいいじゃん!」とレビューで指摘受けることが多いです。
指摘されないけど Ruby っぽくないと思われているんじゃないかと勝手に思い込んでいるイディオム
範囲指定表記
if x > 0 && x < 10
# 何かの処理
end
自分はこう書きます。
if 0 < x && x < 10
# 何かの処理
end
宗教論争を巻き起こしそうな話ではありますが、「ローカル変数との比較の際、『ローカル変数 op 値』とする方が Ruby っぽい」というもの。(元ネタを探したが見つからず。るびまだった気がするが…)
それに対し、自分のコードは数学の数直線に則ったもの。以前の職場で「この方が可読性高いんだ!」という理念のもと、この記述がその職場でのコーディング規約に記載されていたので体に染み付いています。
結局…
「Ruby っぽさ」とはどういうものなんでしょう?Ruby 歴が浅い自分からすると未だによく分からず、これからも先理解できるものなのかもよく分かりません。「こういう方言(言語仕様)なんだ」とすんなり受け入れられるものもあれば、「複数の表現方法があるが、Ruby 固有の表記を良とする」と言われているようなものもあったりするので、個人的にさじ加減が難しく感じます。
プロダクトでは「誰でも(≒Ruby を知らずとも)メンテできる読みやすいコード」が良いのではないかと思う反面、「エレガントな Ruby のコードを書きたいなぁ」という個人的な願望が出てきたりします。「コード量を減らす記述が必ずしも良なのか?」ということに日々悩みながら今後もコードを書いていくと思います。