3

I might be missing something basic with the Scala string interpolation mechanism. What I want to do:

// this could come from a config file, string here to demo
val brown = "BROWN"
val cow = "Moo"
val replaceInMe = "How Now ${brown} ${cow}"

//this does what I eventually want:
val output = s"How Now ${brown} ${cow}"

//But, since the variables 'brown' and 'cow' are defined,
//I really wold like to be able to do something like:
val output = s(replaceInMe) 

Is this even possible?

EDIT: Based on the first answer below, It has to take the variable replaceInMe as input. here I define it as a String, but it is actually a line read from a config file.

3 Answers 3

5

No. The documentation makes it clear that you can only do this with string literals, and not any string object.

This is because when the compiler sees:

s"How Now ${brown} ${cow}"

It transforms it into:

new StringContext("How Now ", " ", "").s(brown, cow)

The compiler can't do this with an arbitrary identifier, because the values are likely set at run time, and not compile time. Imagine that replaceInMe is a value pulled from an external file. How can a string from an external file possibly know about run time variables in the program? What if they weren't defined? With string interpolation this is dealt with via a compile error, which obviously can't happen at run time. At run time, you need another way to deal with missing values.

You are better off using some sort of config library to handle this.

Sign up to request clarification or add additional context in comments.

1 Comment

Got it, makes sense. Thanks!
3

But wait, there's more! It's a compiler and a templating engine!

scala> import javax.script._
import javax.script._

scala> val se = new ScriptEngineManager().getEngineByName("scala")
se: javax.script.ScriptEngine = scala.tools.nsc.interpreter.Scripted@2a742aa2

scala> val animal = new { override def toString = "cow" } // some value
animal: AnyRef = cow

scala> se.put("animal", animal)

scala> val template = "I see a $animal"
template: String = I see a $animal

scala> se.eval(s"""s"$template, she said."""")
res1: Object = I see a cow, she said.

or,

scala> val sc = se.asInstanceOf[ScriptEngine with Compilable]
sc: javax.script.ScriptEngine with javax.script.Compilable = scala.tools.nsc.interpreter.Scripted@2a742aa2

scala> val cs = sc.compile(s"""s"$template, she said."""")
cs: javax.script.CompiledScript = scala.tools.nsc.interpreter.Scripted$WrappedRequest@1dba7721

scala> cs.eval()
res4: Object = I see a cow, she said.

scala> val ctx = sc.createBindings()
ctx: javax.script.Bindings = javax.script.SimpleBindings@1ad28f2       

scala> ctx.put("animal", "frog")
res5: Object = null

scala> cs.eval(ctx)
res6: Object = I see a frog, she said.

Just to show that "compile time" is relative:

scala> val cs = sc.compile("""s"There's no such $thing in scope."""")
<console>:12: error: not found: value thing
       s"There's no such $thing in scope."
                          ^
javax.script.ScriptException: compile-time error
  at scala.tools.nsc.interpreter.Scripted.scala$tools$nsc$interpreter$Scripted$$$anonfun$7(Scripted.scala:113)
  at scala.tools.nsc.interpreter.Scripted$DynamicContext.apply(Scripted.scala:38)
  at scala.tools.nsc.interpreter.Scripted.compile(Scripted.scala:101)
  at scala.tools.nsc.interpreter.Scripted.compile(Scripted.scala:124)
  ... 30 elided

Comments

0

Yes, this is possible. Just define val's brown and cow before replaceInMe like:

In your case its not working because you can't change replaceInMe after its evaluated. Its a value type.

    val brown = "BROWN"
    val cow = "Moo"
    // this could come from a config file, string here to demo
    val replaceInMe = s"How Now ${brown} ${cow}"
    println( replaceInMe )

For more details: http://docs.scala-lang.org/overviews/core/string-interpolation.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.