はじめに
これは Perl Advent Calendar 2020 - Qiita 19日目の記事です。枠が空いていたので飛び入りです。
昨日は nanto_vi さんで Perl の Test2::V0 でオブジェクトの基底クラスを確認する: Days on the Moon でした。 isaをテストしたくなることはけっこうある*1ので、かなりありがたい新機能ですね。
perltidyはPerlのコードフォーマッタです。 設定ファイルがコマンドライン引数を書き下したような形式になっていて、けっこうコツが要ります。
GNU Coding StandardsにもPerl Best Practicesにもそこまで納得感がないので自分で設定を作っていきます。納得感がなくても設定があって自動で適用できるなら従うままだと思うけど、既存コードの書き方からはできるだけ離れないように設定してみました。 Twitter-Textで試しながら調整しました。
.perltidyrc
--add-newlines --add-semicolons --add-whitespace --break-at-old-comma-breakpoints --character-encoding=utf8 --comma-arrow-breakpoints=1 --continuation-indentation=4 --cuddled-else --indent-block-comments --indent-columns=4 --logical-padding --long-block-line-count=1 --maximum-line-length=0 --no-blanks-before-comments --no-indent-closing-brace --no-opening-sub-brace-on-new-line --no-space-for-semicolon --paren-tightness=2 --quiet --trim-qw
設定項目
--add-newlines
perltidyが改行を入れてもよいことにする。
--add-semicolons
perltidyがセミコロンを入れてもよいことにする。
--add-whitespace
perltidyが空白を入れてもよいことにする。
--block-brace-tightness=0
1行のコードブロック {}
の内側には必ずスペースを入れる。 map {$_->name} @users
よりも map { $_->name } @users
がよい。
--brace-tightness=1
コードブロックでない中括弧 {}
のうち、最も外側にあるものの内側にスペースを入れる。
--break-at-old-comma-breakpoints
カンマ区切りのリストがフォーマットされないようにする。普通に書いてて破滅しないのでこうしてる。
--character-encoding=utf8
エンコーディングをutf8に指定する。それはそう。
--comma-arrow-breakpoints=1
1行のリストでない限り、ファットコンマの後ろで改行する。
--continuation-indentation=4
文を改行したあとのインデントはスペース4つ。
--cuddled-else
else
や elsif
の直前で改行しない。デフォルトは --no-cuddled-else
だけど、この書き方が手に馴染んでるのでこうしてる。
# --cuddled-else if ($a) { print('a'); } elsif ($b) { print('b'); } else { print('else'); } # --no-cuddled-else if ($a) { print('a'); } elsif ($b) { print('b'); } else { print('else'); }
--indent-block-comments
コメントと文のインデントを揃える。
# --indent-block-comments if ($a) { print('a'); } # --no-indent-block-comments if ($a) { print('a'); }
--indent-columns=4
インデントはスペース4つ。
--logical-padding
複数行の論理演算があるときインデントをいい感じに揃える。そこまで長い式を書いてないので効果があるかは不明。
--long-block-line-count=1
制御構造ごと? に改行を入れるようperltidyに指示する。
--maximum-line-length=0
1行あたりの文字数上限を取っ払う。現代で1行80文字は短すぎると思う。とはいえちょうどよい上限も見つかってない。ふつうに書いてて1行にいろいろ詰め込むことはないので困ってない。
--no-blanks-before-comments
1行コメントの直前で改行しないようにする。バスバス改行しなくてもよいでしょう。
--no-indent-closing-brace
閉じ括弧の前でインデントしないようにする。
--no-opening-sub-brace-on-new-line
サブルーチン名と括弧の間で改行しないようにする。
--no-space-for-semicolon
C言語形式の for
ループのセミコロンの前にスペースを入れない。滅多にC言語形式の for
ループを書かないのであまり気にしてないけど書くことがあったら気になる。
--paren-tightness=2
括弧 ()
の内側にスペースを入れない。
--quiet
エラーメッセージを出力しない。VSCodeからはKaktus.perltidy-moreを使っていて、エラーログを見ることがない。
--trim-qw
複数行の qw
クォートの周りのスペースを取り除いていい感じにインデントする。
(2021/9/11 追記) うまくいってない点
調整したけどうまくいかなかった点もある。
誰かうまい設定方法を知ってたら教えてください!
この記事を書いた時点ではうまくいっていなかったけど、この記事の.perltidyrcと最新のperltidyだとうまく閉じ括弧のインデントが下げられるようになった。perltidy v20210111で確認したので、ちょうどこの記事から1ヶ月の間に修正されたのだろう。
複数行の qw
クォートの閉じ括弧がインデントされる
# こうなってほしい my @a = ( qw( foo bar baz ), qw( hoge fuga piyo ), ); # こうなる my @a = ( qw( foo bar baz ), qw( hoge fuga piyo ), );
おわりに
perlcriticが比較的柔軟に設定できることと比べると、なんかもうちょっと設定を書きやすくできるとよい気がしますね。
明日は teckl さんです。
*1:Test::DeepからTest2::V0に移行するときはとくに