We get feedback from the compiler. We get feedback from Test-Driven Development. But what sources of feedback lie in between?
This is where linters come in. A linter goes beyond “Does the code compile?” A linter answers questions like, “Is the code idiomatic? Is it stylistically clean? Are there any red flags?”
We want the ability to fearlessly change code. The antidote for that fear is feedback. That’s why I practice Test-Driven Development. TDD gives me fast feedback about whether the behaviors of my components match the desired business rules.
At the other end, compilers don’t understand business rules. But they do understand programming languages. The most basic level of compiler errors tell us whether our code is language compliant. But Xcode also offers:
You can specify what level of Analyzer warnings to use for the “Build” action, as opposed to the “Analyze” action. My practice is to turn up Xcode warnings as far as I can stand them.
So far, all of this analysis is what we might call “strong rules”: they apply to any codebase. But beyond these strong rules, there are softer rules. This is where linters come in.
Soft rules are discovered by the larger community. These rules often express idioms. Such idioms may make sense for one team (or codebase) but not another.
I’ve been using linters since my C and C++ days. Those old linters issued a lot of messages! At the time, much of it seemed like noise. Either they were inherently noisy, or my code was horrible. (Maybe both!) But I don’t remember any way to configure linters with what to report and what to ignore.
Things are a lot better today! Modern linters let you specify which rules you do and don’t want for a particular project.
For Objective-C, I use OCLint. It offers rules like:
…Well, I used to use OCLint. I largely stopped because AppCode’s code inspections give me good feedback with zero set-up. AppCode tells me about:
For Swift, the go-to linter is SwiftLint. It offers rules like:
privatewill silently fail to run, because they’re hidden from the test runner.
What about AppCode “code inspections” for Swift? There’s actually a nice SwiftLint plugin for AppCode. With this plugin, I can instantly see SwiftLint messages within AppCode, before compiling.
Of course, AppCode still reports typos in camel-cased identifiers, since that’s independent of language.
SwiftLint is updated regularly with new rules. Some rules are enabled by default. Others are “opt-in” and won’t take effect unless you explicitly enable them.
To see the current list of rules, type
In the spirit of turn it up to 11, I want to enable as many opt-in rules as I can stand. (Click here to see my SwiftLint configuration for the MarvelBrowser project.) Let me point out the few opt-in rules I don’t enable:
Linters are like warnings on steroids. Experiment with the opt-in rules to see which ones make sense for your projects. When you update a linter, don’t forget to check for new rules you can use.
Test-Driven Development helps us write code that satisfies business rules. Linters (and static analysis in general) help us write code that is cleaner. It’s win-win.
What static analysis tools do you use? And how do you like to use them? Please share in the comments below.
Programming was fun when I was a kid. But working in Silicon Valley, I saw poor code lead to fear, with real human costs. Looking for ways to make my life better, I learned about Design Patterns, Refactoring, and Test-Driven Development (TDD). Programming became fun again! I've now been doing TDD in Apple environments for 17 years. I'm committed to software crafting as a discipline, hoping we can all reach greater effectiveness and joy.
Please log in again. The login page will open in a new tab. After logging in you can close it and return to this page.