Recently, I’ve been working with some fine folks over at Kodeco as a technical editor. Today, some of our hard work has been published. The Swift Apprentice: Fundamentals is available in e-format on their website and in paper format at Amazon. This was my first time doing any editing and I learned so many new things.
The folks over at Kodeco decided that the book was getting a little too unwiedly, so it got broken into two volumes. This is the first one and, as I write this, we are franticly at work on the second. Being a technical editor means that my main responsiblity is to ensure the code examples work and that the authors don’t let any code mistakes slip through in their writing. Of course, as a lifelong corrector of other people’s use of your/you’re and similar, I couldn’t help but fix a few language issues as I saw them. Thankfully I’m not the last editor in the process, which gave me a lot of comfort.
Some of the material in the book has been through eight editions now. A beginner book on Swift has some key points and example that are unchanged since Swift’s early days. However, things that have been recently introduced in the language required all new material. I was assigned to edit the new chapter all about Swift’s support of RegEx.
Regex
One of the things I found most interesting is how Apple decided that some methods that normally take String
parameters could benefit from also taking Regex
arguments. The calling signature looks the same, but just pass in a regular expression. You can either make a variable of type Regex
or simply enclose a regular expression literal with /
as opposed to the "
you would use for a string literal. Here is an example:
let stringToSearch = "Johnny really wished he was named Mary."
stringToSearch.contains("john") // false
stringToSearch.contains(/[Jj]ohn/) // true
In the first instance of using .contains
with “john” the call will fail because there is no exact match of the pattern of letters. Lower-case J and upper-case J are not equal. In the second instance, the regular expression will match on “John” or “john” so it returns true.
Regex Builder
The later part of the chapter starts to really dig into Apple’s new Regex builder format. Although it’s a zillion times more typing to set up than just a quick regular expression string it’s so much easier to read and reason about. In my regular work, I don’t use regular expressions often enough to remember what the differnt symbols mean. So if I didn’t leave myself documentation in the code, I’ll waste a lot of time during a debug session when I suspect the expression is related to the bug. Perhaps the best part about Apple’s implementation of Regex Builder is that you can refactor to it from any regular expression literal. This means that if there is already a regular expression in your codebase, or you find one on StackOverflow that does what you want (or almost does what you want) you can select the expression and then use Xcode’s built in refactor to “Convert to Regex Builder”. Magic.
Difficulties in the Chapter
The chapters of this book are supposed to be small enough chunks of knowledge that the reader can power through them in about half an hour. That really presented a challenge in the Regex chapter. We wanted to present some basics about regular expressions and the Regex
type, but we coudn’t assume that the reader was familiar with them. This meant we had to spend a lot of time talking about “regular expressions” and not necessarily talking about “Swift and regular expressions”.
To me, this became painfully obvious when we had to limit how much we got into using Swift closures and other nifty ways to do capture and replacements near the end of the chapter. Basically, given a string, a regular expression can extract interesting bits and cast them to other types. A number can become an Int
type for example. Additionaly, you can apply logic and other manipulations to the data as it gets extracted.
I think there is easily a whole chapter’s worth of material just on how to structure Regex
types to read and ingest data in a more flexible and less error-prone way than what we do now with JSON and Decodable
. Maybe that can be the topic of another post.