I will usually keep the mailing list exercises separate than the blog, since the blog is more mentor-y in nature. Technical skills are easier to practice in your own time after reading an email than after you’re reading a blog post.
However, some readers have emailed me with their answers and I just have to talk about the exercise.
Your goal with this 15-minute action item is to decrease your resilience to unoptimized code. I want you to hate it. I want you to twitch when you see the first example above. Copy ViewController.swift‘s `viewDidLoad` function to a text file. Fix the pyramid of doom using guards and send me the answer. Don’t use Xcode; don’t use a compiler; do not pass go and collect $200.
I only mentioned the pyramid of doom, but I was hoping some of you wouldn’t stop there. I wanted you to twitch and hate the remaining code after you fixed the pyramid of doom. There’s much more hidden in that code.
From the original code you can see that the pyramid of doom needs fixing. Its ever-increasing indentation and the chain of
ifs reduce readability dramatically. Fixing it is actually straightforward, and a few of you got it right. There’s a few variations, but my first instinct would be to use
filter and then a
guard let ... = filtered.first.
That completes the exercise and if you reached a point similar to this, kudos. You’re exactly at the level I’d expect. Proficient and understands code 💯
However, I was secretly hoping I’d get answers that addressed the code smells that appeared after the pyramid is fixed. For example, let’s step back a bit and see the related function
beginSession is a code smell. It’s a single-use function and it’s obfuscating the fact that
var captureDevice is not needed as an instance variable. You also don’t need to use
try if you’re only going to print the error.
As you can see from my solution, there’s several improvements and small fixes:
- Constants and variable names are more explicit (
- Replaced the
- Removal of optionals (
captureDeviceused to be an optional)
beginSession, to increase readability and reduce jumping around.
var captureDeviceis an instance variable, but it’s only used in
beginSessionand so it’s no longer needed.
And my solution in turn discovers more code smells!
var sessionmay only be needed in
- We now clearly see a point of failure:
captureDevicebeing nil or not being able to add it as an input to session. Do we want to notify the user? Stop execution altogether?
As you can see, the original code presented an obvious code smell (the pyramid of doom) but fixing it is not enough. You should always be striving to fix the tiny things around the code.
In my book, we’ll be dissecting code much like we did right now but with much more detail and with the exact rules that I use to code. You’ll be able to learn my style and spot all of these code smells by following me around as I deconstruct code and make it better.
If you liked this exercise, I send 1 weekly exercise every Friday via email. If you’re interested, sign up and I’ll see you soon!