Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interpolation and multi-line string literals mis-interact #7554

Closed
scabug opened this issue Jun 4, 2013 · 7 comments
Closed

Interpolation and multi-line string literals mis-interact #7554

scabug opened this issue Jun 4, 2013 · 7 comments
Assignees

Comments

@scabug
Copy link

scabug commented Jun 4, 2013

The Scala language spec §1.3.5 indicates that multi-line string literals are not subject to interpolation. For example, you might write a regular expression as """test-config\.xml""" to match a particular string. Unlike in regular strings, the backslash before the period is not escaped.

However, the compiler does not behave correctly when these multi-line literals are used in conjunction with string interpolation. E.g.:

val prefix = "test"
val pattern = s"""${prefix}-config\.xml"""

This should produce the same pattern mentioned above. Instead, it produces a runtime error about an invalid string. You can work around this by double-escaping any backslashes, but this is not consistent with the language specification.

scala.StringContext$InvalidEscapeException: invalid escape character at index 7 in "-config\.xml"
	at scala.StringContext$.treatEscapes(StringContext.scala:229)
	at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:90)
	at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:90)
	at scala.StringContext.standardInterpolator(StringContext.scala:123)
	at scala.StringContext.s(StringContext.scala:90)
	at .<init>(<console>:9)
	at .<clinit>(<console>)
	at .<init>(<console>:7)
	at .<clinit>(<console>)
	at $print(<console>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:734)
	at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:983)
	at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:573)
	at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:604)
	at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:568)
	at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:745)
	at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:790)
	at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:702)
	at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:566)
	at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:573)
	at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:576)
	at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:867)
	at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:822)
	at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:822)
	at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
	at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:822)
	at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:83)
	at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
	at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
	at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
@scabug
Copy link
Author

scabug commented Jun 4, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7554?orig=1
Reporter: Sarah Gerweck (gerweck)
Affected Versions: 2.10.1

@scabug
Copy link
Author

scabug commented Jun 4, 2013

Sarah Gerweck (gerweck) said:
Sorry, fix formatting.

@scabug
Copy link
Author

scabug commented Jun 4, 2013

@paulp said:
I don't know what language you think excludes tripled quoted strings from string interpolation, but this is the expected behavior. I see nothing for you to misinterpret this way; and whatever it is, it's about string literals, which start with " or """. Once you put an "s" in front of it, it is a string-interpolated string literal.

@scabug scabug closed this as completed Jun 4, 2013
@scabug
Copy link
Author

scabug commented Jun 4, 2013

@paulp said:
Oh, you want the triple-quoted semantics in the interpolator. It the context of scala it is very confusing to use "interpolation" to speak of backslash escapes at the same time you are making reference to the thing we call string interpolation.

The triple vs single quoted issue is an example of string interpolation being broken by design, but it's not a spec violation. String interpolation happens after the literal, and it's the interpolator which is processing the backslash.

@scabug
Copy link
Author

scabug commented Jun 4, 2013

Sarah Gerweck (gerweck) said:
I agree that interpolation is a confusingly overloaded term in this context, but I don't see how this isn't a bug.

The language spec says about triple-quoted strings: "None of the escape sequences in (§1.3.6) is interpreted." Are you suggesting that putting an s in front of a triple-quoted string means that it's no longer a triple-quoted string? As far as I know, the escape character for Scala's prefix interpolator is $, so I don't see why it would override the language spec's claim that backslashes are not interpreted inside triple quotes.

The whole point of triple-quoted strings is to disable all the quoting rules and let you paste in strings verbatim. I also don't see why it would be desirable to require escaping only in the case of an interpolated string, even if the language spec didn't state clearly that you don't need escaping in a triple-quoted string.

@scabug
Copy link
Author

scabug commented Jun 4, 2013

@paulp said:
The interpolator processes the string literal. Placing an "s" in front of it means code will run which might treat the backslashes any way imaginable. The particular way the "s" interpolator treats them, and this is not part of the specification nor covered by it, is the way you are witnessing.

And it isn't "desirable" that it's this way, that's why I said it is an example of their being broken by design.

If it assists in deciphering intent, every word you are parsing in the language spec was written before string interpolation was even a notion. Anything which sounds like it refers to string interpolation is coincidental. The spec has been abandoned so you have to apply some filters when trying to make sense of it. It reasonably adequately summarizes the language of 2006, seven years ago.

@scabug
Copy link
Author

scabug commented Jul 9, 2013

@SethTisue said:
I think this adequately covered in the text of SIP-11, http://docs.scala-lang.org/sips/pending/string-interpolation.html ...which in some hypothetical future will be merged into the language spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants