Rails で
rails generate scaffold item name
とかなんとかやって自動的に生成されるコントローラーのコードに,理解不能なインデントがある。
Rails 8.1.1 で上記をやってみると,こうなる
class ItemsController < ApplicationController
before_action :set_item, only: %i[ show edit update destroy ]
# GET /items or /items.json
def index
@items = Item.all
end
# 中略
private
# Use callbacks to share common setup or constraints between actions.
def set_item
@item = Item.find(params.expect(:id))
end
# Only allow a list of trusted parameters through.
def item_params
params.expect(item: [ :name ])
end
end
private のあとの二つのメソッド定義のインデントが,無駄に一段深くなっている。
記憶ではかなり昔の Rails バージョンからずーっとこのスタイルだ。
Rails 開発陣はこれをよしとしているのだろう。しかし私にはまったく理解できない。
初めて見たとき,なんとなく
class X
private
end
という構文に見立てているのかな?と思った。
private はもちろん,クラス定義式の構文の一部ではない。
ただのメソッドだ。上のコードでは,X というクラスの private というメソッドを呼び出している(クラス定義式内の self はそのクラス自身だったね)。
これにより,それ以降に書かれたメソッド定義式で定義されるメソッドが private メソッドになる,と。そういうことだ。
そのことを分かったうえで,あえてあたかも class〜private〜end という構文であるかのように見せているのかな,と思った。
しかし,そうだとしても
class X
# なんとかかんとか
private
def hoge
# うんちゃら
end
end
というインデントは非常に気持ち悪い。
最後に end が 二階級特進 している。
コードが長い場合,末尾の
end
end
を見て,一瞬「なんかやらかしたか?」と思ってしまいそう。
構文に見立てるのであれば
class X
# なんとかかんとか
private
def hoge
# うんちゃら
end
end
と書いたほうが
def moge
# なんとか
rescue
# かんとか
end
などと整合して,まだマシなのではないだろうか。
しかし,私はやっぱり
class X
# なんとかかんとか
private
def hoge
# うんちゃら
end
end
と書きたいし,そう書いている。
メソッド private の呼び出しも,メソッド hoge の定義式も,どちらもクラス X の定義式のいわば「一番上のレベルの」構成要素であって,同じインデントレベルで書くのが文法に照らして最も素直ではないだろうか。
それと,老婆心ながら,Rails から入った Ruby 初心者の方が,自動生成コードの変なインデントによって private を誤解しないだろうか,ということも心配になる。
たぶん,探せば Rails がこうなっている理由について書かれた文があるんだろうけど,私(へっぽこ)には探す能力がないし気力もない。