Multiline Strings without leading spaces in Ruby
Usually, in ruby the simpliest way of holding pretty formatted multiline strings сonsists in usage of string concatenation, let’s look on a simple sql query :
We can indent this code how we want and place it where we want and it have as much spaces as we want - not more, not less. But this method has one crucial disadvantage. Consider having a very-long-long-line-text. So, in accordance to this method we need to split text line by line and join it with quotes and plus. This doesn’t seem to be a good way. Let’s try something else.
Ok, the other way of formatting this query consists in in-place raw query usage, we had to start from this method :
Hmm, something what we want! But what can we do with this leading spaces? They are not necessary and sometimes they could ruin code.
I faced with this problem when I had to programmatically send an email to our customers. I used SMTP protocol, where every space counts, so every single line command should not have leading spaces. And of course we want to have a method without splitting source text by line.
So, the idea is to remove preceding spaces and tabs. That’s where regular expression help us.
The algorithm is following: if line of text starts with one or more spaces or tabs just remove them.
Regular expression FTW
Here I’ll briefly introduce you to regular expressions. RegExps are one of the most powerful tools every programmer should know. Oh, not only programmers, but system administrators and engineers also should know them. Every regular expression consists of flags and ordinary symbols, so the idea here is to learn what every flag mean. In our example the final regular expression looks like /^( |\t)+/, let’s figure out what every part of it is :
- /.../ - two backslashes shows us that everything between them is a regular expression, sometimes this slash delimeter could differ, for example a hash symbol # or something else.
- ^ is start line flag, so every further symbol after ^ shows as that line should start from this symbol, for example ^A matches to line starting from A.
- (a|b|c|d) - this construction matches to character that could be a or b or c or d. But it could be only one character. It also capturing the final result, as a result we could know what symbol exactly have been matched. In our example ' ' is space character and \t is tab character.
- + matches to one or more previous character.
Reading the whole regexp /^( |\t)+/ will look something like this - match every single line, which starts from one or more tab or space.
Woot! That’s what we need. Now, using gsub in ruby we can replace all matched substrings in text with no text
Applying this filtering exactly in place where we want to use it, we came to complete listing.
Complete listing
and result