2017年4月15日土曜日

凛としてSwift (血闘編ノ壱)

割と凹みやすいアルマイトな性格です。

いくつかの軽い(Swift成分の低い)プロジェクトにSwiftLintを導入してみて、なんとなく把握できたので、次はSwift率の高いプロジェクトにSwiftLintを導入してみることにしました。

予想通り、数え切れないワーニングとエラーが吐かれますね。ため息が出ますね。当然これをちくちくと直していかなければならないのですが、先頭からひとつひとつやっていると、最後にたどり着く前にメンタルがやられそうです。

そこでXcodeの問題ナビゲーターからいったん目をそらして、個々の対処法について考えてみます。
  1. 素直に修正する。
  2. 特定の箇所だけLintの例外にする。
  3. ymlファイルを編集して、Lintのルールを緩める。
  4. 放置する。
  5. SwiftLintの導入を断念する。
まず5.は避けたいですね。せっかくなんだし。何より、現行のソースがLint適用済みになれば、その後はソースを修正する都度Lintが指摘してくれるわけですから、辛いのは最初だけです。

次に4.は「ダメ、絶対!」ですね。これから先ソースを修正していくのに、修正しなければならないエラーやワーニングが、Lintのワーニングに埋もれてしまってはバグの温床になります。

そうなると1.2.3になりますが、できるだけ1.で頑張って、ちゃんとした理由がある時にかぎって2.、それでもしょうがないときは3.ということにします。

そうしよう、そうしよう。

で、そらしていた目をワーニングの山に向けます。先頭から順にやっていくのも芸がないですよね。それに全て修正し終わってからgitのコミットをしていたのでは粒度が大きくなるので、うっかりエンバグしていたときに、追いかけるのが大変になりそうです。そこで少しだけ工夫をします。

ymlファイルを編集して、エラー/ワーニングの元になっているルールを一時的に全てdisabledにします。そしてエラー/ワーニングがなくなった状態から、disabledにしたルールをひとつずつ有効にして、同じワーニング毎に潰していきます。これなら修正対象は全て同じ種類になるので、作業が楽になります。上記1,2,3の判断もしやすくなりますし、さらにコミットの粒度も下がります。

ymlファイルを抜粋すると、こんな感じですか。
disabled_rules: # rule identifiers to exclude from running
- line_length # no limit on length of line
- trailing_whitespace # be able to one empty line
- large_tuple # tuple can hold values more than three
- opening_brace #temporary
- trailing_semicolon #temporary
- trailing_comma #temporary
- cyclomatic_complexity #temporary
- control_statement #temporary
- vertical_whitespace #temporary
- class_delegate_protocol #temporary
- weak_delegate #temporary
- redundant_optional_initialization #temporary
- statement_position #temporary
- force_cast #temporary
- colon #temporary
- unused_closure_parameter #temporary
- syntactic_sugar #temporary
- empty_count #temporary
- variable_name #temporary
- type_body_length #temporary
- function_body_length #temporary
- file_length #temporary
- function_parameter_count #temporary
opt_in_rules: # some rules are only opt-in
…以下略
view raw .swiftlint.yml hosted with ❤ by GitHub

これで、エラー/ワーニングが出力されなくなったので、機械的に修正できる簡単なものから手をつけていきます。

opening_braceを、disabled_rulesから削除すると、こういったところが指摘されます。
override func viewDidLoad()
{
super.viewDidLoad()
…省略
}

えー、Paul Hegarty先生だってこう書いてたぢゃん。 Objective-Cの流れでこうなんじゃないのー、って愚痴りながら修正します。

override func viewDidLoad() {
super.viewDidLoad()
…省略
}

この他にもこういうところにワーニングが出ますね。
if let ks = KeySignature(rawValue: keySignature){ //←こことか
…省略
}else{ //←こことか
…省略
}

If文の条件にカッコが必要ないことなど、スッキリした文法になっている分、各語句の前後や、{ } の前後の空白はきちんと入れましょうということですね。


凛としてSwift (血闘編ノ弐)」につづく。


こんな風に手を入れているチューナーアプリです。よろしくね。


♪♪♪


こちらもどうぞ。
凛としてSwift
凛としてSwift (血闘編ノ弐)
凛としてSwift (血闘編ノ参)
帰ってきた凛としてSwift(くるくる編)