Multi-Line Strings
AS3 has never had very good support for multi-line strings… until now. Today’s article discusses the proper and improper ways of writing multi-line strings and delves into the bytecode so you really understand what’s going on.
Perhaps the most natural way to write a multi-line string would be like this:
var str:String = "A B C";
But if you know anything about AS3, you’ll know that doesn’t work. You’re greeted with several compiler errors:
/Users/jackson/Desktop/MultiLineString.as:28 Syntax error: A string literal must be terminated before the line break. var str:String = "A\n ^ /Users/jackson/Desktop/MultiLineString.as:29 Syntax error: Expecting either a 'semicolon' or a 'new line' here. B\n ^ /Users/jackson/Desktop/MultiLineString.as:29 Error: Unexpected character. '\' is not allowed here B\n ^ /Users/jackson/Desktop/MultiLineString.as:29 Error: Access of possibly undefined property B. B\n ^ /Users/jackson/Desktop/MultiLineString.as:29 Error: Access of possibly undefined property n. B\n ^ /Users/jackson/Desktop/MultiLineString.as:30 Syntax error: A string literal must be terminated before the line break. C\n"; ^ /Users/jackson/Desktop/MultiLineString.as:30 Syntax error: Expecting either a 'semicolon' or a 'new line' here. C\n"; ^ /Users/jackson/Desktop/MultiLineString.as:30 Error: Unexpected character. '\' is not allowed here C\n"; ^ /Users/jackson/Desktop/MultiLineString.as:30 Error: Access of possibly undefined property C. C\n"; ^ /Users/jackson/Desktop/MultiLineString.as:30 Error: Access of possibly undefined property n. C\n"; ^
Instead, AS3 programmers resort to one of two methods. The first is to concatenate multiple strings with the +
operator:
var str:String = "A" + "B" + "C";
The second is to manually concatenate the strings to avoid the runtime expense of string concatenation:
var str:String = "ABC";
This latter approach is to simply avoid multi-line string altogether. But do we need to go to these extremes to avoid a performance problem? As it turns out, the ASC 2.0 compiler is pretty smart when using full release-mode settings:
--verbose-stacktraces=false -debug=false -optimize=true
As an example, consider the following multi-line string:
var str:String = "A" + "B" + "C";
Here’s the bytecode that gets generated by ASC 2.0:
pushstring "ABC"
coerce_s
Happily, the compiler was smart enough to concatenate the strings at compile time rather than run time.
Now for a word of warning: do not omit the +
operators as is allowed in C or C++ code. The strings will not by concatenated. You won’t even get a compiler error or warnings. For example, consider this erroneous attempt at a multi-line string:
var str:String = "A" "B" "C";
The compiler interprets this as the first line:
var str:String = "A"
Which is alright since semicolons are optional in AS3. Then there are two more statements, one of which has a semi-colon:
"B" "C";
So the compiler generates the following code (annotations mine):
// Push "A" and save it to the "str" local variable pushstring "A" coerce_s setlocal1 // Push "B" and then immediately pop it pushstring "B" pop // Push "C" and then immediately pop it pushstring "C" pop
Not only is the multi-line string not concatenated properly, but two more strings are properly created, pushed, and popped for absolutely no reason whatsoever.
In summary, this is how to create a multi-line string in AS3. The compiler will concatenate the string for you at compile time.
var str:String = "A" + "B" + "C";
And this is how to not create a multi-line string in AS3. The compiler will not concatenate the string for you at compile time, will not generate code that concatenates the string at run time, and will instead generate a SWF with the unused “B” and “C” strings that pointlessly pushes and pops them on the stack at run time.
/////////////////////// // Note: no + operators /////////////////////// var str:String = "A" "B" "C";
Spot a bug? Have a question or suggestion? Post a comment!
#1 by clark on December 23rd, 2013 ·
Mate, your website is amazing. Keep up the great work through 2014. Have a good xmas and new year.
#2 by jackson on December 23rd, 2013 ·
Thanks. I’ve still got one more article in 2013 and there will be plenty more in 2014!
#3 by clark on December 23rd, 2013 ·
Glad to hear :D
I am doing a personal project just messing around with some movement and math. I started with generic AS3 Math calls. With each article here I have tried to apply the concepts to my project and the result is a huge performance increase across the board.
I wanted to ask, do you keep a personal library anywhere with your findings? I shudder to think of its performance vs the native API.
#4 by jackson on December 24th, 2013 ·
All of these articles are completely standalone. Usually it’s just one
.as
file that I compile on the command line. Other times it’s two or three files, but they’re not really linked together into any cohesive library. For professional purposes I, of course, have much larger codebases.For your math-heavy projects, check out the link to Benjamin Guihaire on the right column of this page under “On-Topic Sites”. He’s written quite a few really good articles on AS3 math optimization lately and you may be able to get quite a few speedups by implementing some of his techniques.
#5 by Smily on December 23rd, 2013 ·
For actual multiline blocks of strings you can use a CDATA xml section and toString it. This even preserves newlines and spacing as well as avoiding interline cruft in exchange for a bit more verbosity and probably slower runtime execution.
It’s great for inline text blocks though, e.g. AGAL:
vs.code = ().toString();
#6 by Smily on December 23rd, 2013 ·
Welp, blog ate my cdata, after the opening parenthesis it should be and then the closing parenthesis.
#7 by Smily on December 23rd, 2013 ·
Okay, I look crazy now. Like this http://pastebin.com/xyudz0jx
#8 by jackson on December 23rd, 2013 ·
Thanks very much for this suggestion. It’s arguably an easier way to create multi-line strings. Within the start and end lines it’s certainly a lot cleaner to my eyes. There’s the added benefit that you automatically get newlines in your string. That could be an annoyance though if the string you’re trying to create isn’t supposed to have newlines, such as the examples in the article. It also creates a larger string due to all of the whitespace unless you don’t indent it. That’s fine for most purposes, though. The biggest issue is certainly that it creates an XML document and then traverses it to build a string. Again, for most purposes that’s probably fine, but the concatenation method in the article is, as pointed out, completely free at run time. Still, it’s always nice to have more ways to build these strings to suit more developers’ individual tastes.
I fixed the formatting on your original comment.
#9 by bennett on December 30th, 2013 ·
Hey Jackson,
Great blog, I read it every week. What do you use to see compiler code?
#10 by jackson on December 30th, 2013 ·
Thanks. I use the
swfdump
command-line utility that comes with the AIR SDK. Use it like this:Then check out
/path/to/output.txt
and you’ll see all the bytecode that the compiler generated.#11 by Taaniel on December 31st, 2013 ·
I use for that SWF investigator. http://labs.adobe.com/technologies/swfinvestigator/
#12 by bennett on December 31st, 2013 ·
great thank you!
#13 by bech on December 31st, 2013 ·
Another approach is to just put a backslash at the end of each line without the “n”:
var str:String = “A\
B\
C”;
trace(str); // ABC
#14 by jackson on December 31st, 2013 ·
That’s a good approach, too. It’s a good option if you want to preserve whitespace, too:
Output: