3

I came up with a trick to use named parameters in Scala. Is there a better way? What are the downsides?

<x>
  |CREATE OR REPLACE FUNCTION myFunction({columns.map(column => column.name).
                                          mkString(",\n")})
  |RETURNS BOOLEAN AS $$
  |BEGIN
  | -- more stuff
  |END;
  |$$ LANGUAGE 'plpgsql';
  |</x>.text.stripMargin

Watch out for ampersands in the XML body; they need to be "quoted" as &amp; or placed in braces like {"&"}. Do I win a prize for ugliest code? :-)

Ralph
  • 31,584
  • 38
  • 145
  • 282
  • 1
    What is it exactly that you're trying to do? – Jean-Philippe Pellet Apr 28 '11 at 19:08
  • @Jean-Philippe Pellet: I need to generate a rather large SQL function in my Scala code, with replacement of parts of the function with calculated pieces (like `args` above). – Ralph Apr 28 '11 at 19:11
  • I really like your idea! I often had the same problem, not only with SQL. Sometimes one constructs a fat string with format having many many format arguments. – Peter Schmitz Apr 28 '11 at 19:44
  • @Peter Schmitz: I am also putting Scala code into the inner braces that actually calculates the columns names, etc.: `{columns.map(column => column.name).mkString(",\n")}` -- see update in the question. – Ralph Apr 28 '11 at 20:28
  • @Ralph: Yes that´s the trick! So you have the evaluation of the arguments in braces at the right place and not at the end in a long argument list of `format`. And that´s what I like. I often got confused with that long argument list. – Peter Schmitz Apr 28 '11 at 20:34
  • 1
    possible duplicate of [Better String formatting in Scala](http://stackoverflow.com/questions/4051308/better-string-formatting-in-scala) – Daniel C. Sobral Apr 28 '11 at 20:36

3 Answers3

2

Good news! Scala 2.10.0 introduced real, functional string interpolation!

The docs are available here: http://docs.scala-lang.org/overviews/core/string-interpolation.html

Here's a quick sample:

In Python, I used to do things like:

print "%(from)s -> %(to)s" % {"from": foo, "to": bar}

now, in Scala 2.10.0+, we can do this!

val from = "Foo"
val to = 256
println(s"$from -> $to")  // Prints: Foo -> 256

There's also some format string support as well, which is pretty awesome:

val from = 10.00  // USD
val to = 984.30  // JPY
println(f"$$$from%.2f -> $to%.2fJPY")  // Prints: $10.00 -> 984.30JPY

Since the second example has some minimal type expressiveness, it also gives us some basic type checking as well!

val from = 10.00
println(f"$$$from%d") // <-- Type error! Found "Double", required "Int"!
2

I think that if you need a string formater on this scale, you need a Builder or a templating engine, like Velocity. Incidentally, I've found Scala's good for builders and DSLs.

sblundy
  • 60,628
  • 22
  • 121
  • 123
  • I've written a wrapper for velocity two years ago that fits the use case of the question. http://kneissl.eu/open-source/scala-velocity/ – mkneissl Apr 28 '11 at 20:09
  • @mkneissl: Almost gets around the lack of a preprocessor. :-) – Ralph Apr 28 '11 at 20:30
2

If you don't mind a compiler plugin, try Johannes Rudolph's Scala Enhanced Strings. I like it a lot.

Alex Cruise
  • 7,939
  • 1
  • 27
  • 40