what means predefined string format? - scala

This is my code and I got comment said " can I use the predefined string format?", what is predefined string format, how can I do that?
val uri = new URI(baseUrl + "?provider=" + provider + "&format=" + format)

This is a clean "Scala" way to do this:
val uri = new URI(s"$baseUrl?provider=$provider&format=$format")
A decent editor like IntelliJ IDEA will highlight this so that it is clear which parts are code and which parts are plain text.

This is not a proper way of constructing a URI, and neither is using a string interpolator such as s"..." as suggested in the other answer or by your coworker. The reason is that it is going to break as soon as provider or format contain “weird” characters such as # or &. That can lead to all kinds of bugs, including security vulnerabilities.
Unfortunately, Scala doesn't come with an easy built-in way to construct URI query strings. You should use some URI abstraction from a library such as akka http or http4s.
For instance, with http4s you can write
val uri = uri"https://stackoverflow.com".withQueryParam("provider", provider)
That will take care of all the necessary escape sequences and the like.

Related

How to create string with variable similar to what template literals does in JS ES6?

In the following code, I want to allow read for a path if a document exiest in another path.
function isRemoteDocExist(path) {
return exists(/databases/$(database)/documents/$(path));
}
match /some/path/{id} {
allow read: if isRemoteDocExist(`other/path/$(id)`); // <-- How do I do this?
}
There is no syntax for this with Firebase security rules. The rules syntax may look like JavaScript, but it definitely is not that.
The only way to compose strings with security rules is with the operations provided by String type objects. And that's pretty much just the concatenation operator +. There is no string template like ES6.
Furthermore, it looks like you're trying to mix the Path type with the String type to build a new Path. You might have problems with the way you're doing it now. If you want to build a Path programmatically, you should compose a String first, then convert that into a Path later using the path() function, as described in the linked documentation for Path.

Log when a character is replaced in Scala

Right now, we are using
val codec = scala.io.Codec.UTF8
codec.onMalformedInput(CodingErrorAction.REPLACE)
to simply replace bad characters. I would like to know if there is a way to know that the replacement occurred? We would like to inform our customers that the data they sent us was malformed. Is there a way to do this in Scala or Java?
Thanks

Logging syntax for Play Framework 2 in Scala

This is a really silly question, but how can you do convenient formatting of log strings in Play Framework 2 (and in Scala?).
I've googled but its very difficult to find an example, essentially most links are talking about configuring Logback in the first place which I've done fine.
I'm basically trying to find the best stylistic way to do something like:
if(Logger.isDebugEnabled)
Logger.debug("Modified: Id = '" + real_session_id + "', Modified = " + modified.toString)
Coming from a C# background (and log4net) I'd assume you could do something like:
if(Logger.isDebugEnabled)
Logger.debug("Modified: Id = '{0}', Modified = {1}", real_session_id, modified.toString)
But I can't see how this would work with the trait the way it is defined. I've also seen vague references to how you might be able to avoid checking Logger.isDebugEnabled by using a lazy evaluative syntax like:
Logger.debug("Modified: Id = ${real_session_id}, Modified = ${modified.toString}")
That uses Scala macros - but again, that doesn't work and I can find very little information about it.
Am I missing something really blatant here?
The framework used for logging is logback. When you type : Logger.debug, the isDebugEnabled is already implicitly checked.
For the syntax of logging, use the Scala string interpolation.
Logger.debug(s"Modified: Id = '$real_session_id', Modified = $modified.toString")
Why not just use the standard String interpolation capabilities of the language/stdlib? http://docs.scala-lang.org/overviews/core/string-interpolation.html
I apologise if I've missed something crucial about your question.
As to avoiding the if (Logger.isDebugEnabled) check, if the logging framework is not providing some sort of lazy evaluation scheme for arguments passed into it, I would just first consider defining my own wrappers:
object MyLazyLogger {
def debug(msg: => Any) =
if (Logger.isDebugEnabled) Logger.debug(msg)
}
Also, I don't think the way in which you interpolate stuff into the string has anything to do with not evaluating the arguments to debug() if logging is disabled—if debug() declares that it eager-evaluates any arguments passed into it, there's no way that I can see you can change to lazy evaluation at the call site by just using a "special form" of string interpolation. (I'd be happy if anyone proved me wrong here and taught me something new :))
Disclosure: I'm not familiar with Play (yet), so I'm just taking a shot at a general approach here.

Embedding XML (and other languages?) in Scala

I'm wondering how the scala.xml library is implemented, to get an Elem-instance out of XML.
So I can write:
val xml = {
<myxml>
Some wired text withoud "'s or code like
import x
x.func()
It's like a normal sting in triple-quotes.
</myxml>
}
xml.text
String =
"
Some text wired withoud "'s or code like
import x
x.func()
It's like a normal sting in triple-quotes.
"
A look at the source code doesn't gave me the insight, how this is achieved.
Is the "XML-detection" a (hard) scala language feature or is it an internal DSL? Because I would like to build my own things like this:
var x = LatexCode {
\sqrt{\frac{a}{b}}
}
x.toString
"\sqrt{\frac{a}{b}}"
or
var y = PythonCode {
>>> import something
>>> something.func()
}
y.toString
"""import something ..."""
y.execute // e.g. passed to python as python-script
or
object o extends PythonCode {
import x
x.y()
}
o.toString
"""import x...."""
I would like to avoid using such things like PythonCode { """import ...""" } as "DSL". And in scala, XML is magically transported to a scala.xml-Class; same with Symbol which I can get with val a = 'symoblname, but in the source code there's no clue how this is implemented.
How can I do something like that on myself, preferably as internal DSL?
XML is a scala language feature (*) - see the SLS, section 1.5.
I think that string interpolation is coming in 2.10, however, which would at least allow you to define your own DSL:
val someLatex = latex"""\sqrt{\frac{a}{b}}}"""
It's an experimental feature explained more fully in the SIP but has been additionally blogged about by the prolific Daniel Sobral. The point of this is (of course) that the correctness of the code in the String can be checked at compile time (well, to the extent possible in an untyped language :-) and your IDE can even help you write it (well, to the extent possible in an untyped language :-( )
(*) - We might expect this to change in the future given the many shortcomings of the implementation. My understanding is that a combination of string interpolation and anti-xml may yet be the one true way.
It's an XML literal, just like "foo" is a string literal, 42 is an integer literal, 12.34 is a floating point literal, 'foo is a symbol literal, (foo) => foo + 1 is a function literal and so on.
Scala has fewer literals than other languages (for example, it doesn't have array literals or regexp literals), but it does have XML literals.
Note that in Scala 2.10 string literals become vastly more powerful by allowing you to intercept and re-interpret them using StringContexts. These more powerful string literals would allow you to implement all of your snippets, including XML without separate language support. It is likely that XML literals will be removed in a future version of the language.

Is string concatenation in scala as costly as it is in Java?

In Java, it's a common best practice to do string concatenation with StringBuilder due to the poor performance of appending strings using the + operator. Is the same practice recommended for Scala or has the language improved on how java performs its string concatenation?
Scala uses Java strings (java.lang.String), so its string concatenation is the same as Java's: the same thing is taking place in both. (The runtime is the same, after all.) There is a special StringBuilder class in Scala, that "provides an API compatible with java.lang.StringBuilder"; see http://www.scala-lang.org/api/2.7.5/scala/StringBuilder.html.
But in terms of "best practices", I think most people would generally consider it better to write simple, clear code than maximally efficient code, except when there's an actual performance problem or a good reason to expect one. The + operator doesn't really have "poor performance", it's just that s += "foo" is equivalent to s = s + "foo" (i.e. it creates a new String object), which means that, if you're doing a lot of concatenations to (what looks like) "a single string", you can avoid creating unnecessary objects — and repeatedly recopying earlier portions from one string to another — by using a StringBuilder instead of a String. Usually the difference is not important. (Of course, "simple, clear code" is slightly contradictory: using += is simpler, using StringBuilder is clearer. But still, the decision should usually be based on code-writing considerations rather than minor performance considerations.)
Scalas String concatenation works the same way as Javas does.
val x = 5
"a"+"b"+x+"c"
is translated to
new StringBuilder()).append("ab").append(BoxesRunTime.boxToInteger(x)).append("c").toString()
StringBuilder is scala.collection.mutable.StringBuilder. That's the reason why the value appended to the StringBuilder is boxed by the compiler.
You can check the behavior by decompile the bytecode with javap.
I want to add: if you have a sequence of strings, then there is already a method to create a new string out of them (all items, concatenated). It's called mkString.
Example: (http://ideone.com/QJhkAG)
val example = Seq("11111", "2222", "333", "444444")
val result = example.mkString
println(result) // prints "111112222333444444"
Scala uses java.lang.String as the type for strings, so it is subject to the same characteristics.