Multi-line Strings · Dec 19, 06:09 PM by Dylan Doxey
So, there you are, writing a script which sends an email to each of the staff wishing them each a nice day. To ensure that you are having a nice day also, you want your code to look nice and be maintainable by the next guy that comes along to change, debug or fix it later.
my $name = 'Mr. Pibb'; my $message = <<TEMPLATE; Dear $name, please have a nice day. Thank you. Sincerly, the Management. TEMPLATE
Well, here's the thing... I personally don't like that syntax for doing multi-line strings. Yet of all the languages I've worked with, this solution offered by Perl seems to be the best thing going. (There is the possibility of keeping the text of the message in a template file to be read an processed without mucking up your code layout. But that's for a different post.)
- The code layout reflects the layout of the finished product.
- It's concise.
- Variables can be dereferenced within its context.
- In a body of tidily arranged code, this blasts your layout with an unsightly discontinuity of layout.
- The aesthetic of this just makes me feel uneasy and I feel somewhat obsessed with how to convince everyone to agree with con #1.
So, you might be inclined to ask what I'd suggest as an alternative.
my $message = "Dear $name,\n\nplease have a nice day.\n\nThank you.\n\nSincerly, the Management.";
This is the obvious choice.
Pros:- It's concise.
- It doesn't interfere with your layout and indentation pattern.
- Simplicity -- any programmer in the world can read and understand it.
- Weak maintainability -- it's too fragile and easy to buggify when making changes.
- The end result is not obvious at a glance.
- It's just ugly.
Let's try breaking it up to make the individual lines stand out.
my $message = "Dear $name,\n\n"
. "please have a nice day.\n\n"
. "Thank you.\n\n"
. "Sincerly, the Management.";
Here's a big improvement over just jamming it all together in a single line.
Pros:- Simplicity -- anyone can understand this at a glance.
- End result is similar to the layout of the code.
- This doesn't interfere with your code layout and indentation pattern.
- It's still a bit cluttered and subject to getting bugged up during maintenance.
- This still doesn't accurately represent the appearance of the finished product.
Let's try something that will better suggest the rectangularity of the intended result.
my $message = "Dear $name," . "\n"
. "" . "\n"
. "please have a nice day." . "\n"
. "" . "\n"
. "Thank you." . "\n"
. "" . "\n"
. "Sincerly, the Management.";
Here's getting a little closer to my vision for a clean multi-line string definition.
Pros:- Simplicity -- anyone can understand this at a glance.
- End result is very similar to the layout of the code.
- This doesn't interfere with your code layout and indentation pattern.
- This is still cluttery and easily bugged up during maintenance.
- This is still not extremely representative of the end result.
How about something more structured than a sequence of concatenated strings.
my $message = join "\n", (
"Dear $name, ",
" ",
"please have a nice day. ",
" ",
"Thank you. ",
" ",
"Sincerly, the Management. ",
);
Whoa, now we're getting somewhere. This gives us a strong sense of the shape and layout of the target document without compromising our code layout at all.
- Most any programmer should be able to understand this at a glance.
- End result is extremely similar to the layout of the code.
- This doesn't interfere with your code layout and indentation pattern.
- This includes a bunch of trailing white-space for each line.
- The inline join statement is a bit of a distraction.
my $message = join "\n", map { $_ =~ s/(\A [\s]* | [\s]* \z)//msxg } (
"Dear $name, ",
" ",
"please have a nice day. ",
" ",
"Thank you. ",
" ",
"Sincerly, the Management. ",
);
Nice.
- End result is very similar to the layout of the code.
- This doesn't interfere with your code layout and indentation pattern.
- The inline map statement is a big noisy unaesthetic appendage.
- This is easily bugged up during maintenance.
my $message = multiline_string(
"Dear $name, ",
" ",
"please have a nice day. ",
" ",
"Thank you. ",
" ",
"Sincerly, the Management. ",
);
sub multiline_string {
return join "\n", map { $_ =~ s/(\A [\s]* | [\s]* \z)//msxg } @_;
}
Better.
- The intended result is very similar to the layout of the code.
- This doesn't interfere with your code layout and indentation pattern.
- The "multiline_string" function call is unique to your organization which would be weird to newcomers.
my $message =
+----------------------------+
| Dear $name, |
| |
| please have a nice day. |
| |
| Thank you. |
| |
| Sincerly, the Management. |
+----------------------------+
;
Now you're talking!
This is a snippet out of my fantasy language.
- Although not identical to the final product, the code is extremely representative, as if you were writing pseudo code for another human being.
- The parser knows your intended line lengths and can trim or wrap accordingly.
- This doesn't interfere with your code layout and indentation pattern.
- There is no known language which would parse this as a multi-line string declaration.
my $message =
+----------------------------+
| Dear $name,
|
| please have a nice day.
|
| Thank you.
|
| Sincerly, the Management.
+----------------------------+
;
Perhaps this variation could suggest no trailing white-space.
UPDATE: Now see Filter::BoxString on CPAN for my implementation of this idea.

Commenting is closed for this article.
Caching Remote Images How much does it cost to drive a Jeep?
