Logging syntax for Play Framework 2 in Scala - 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.

Related

Scala: when to use explicit type annotations

I've been reading a lot of other people's Scala code recently, and one of the things that I have difficultly with (coming from Java) is a lack of explicit type annotations.
It's certainly convenient when writing code to be able to leave out type annotations -- however when reading code I often find that explicit type annotations help me to understand at a glance what code is doing more easily.
The Scala style guide (http://docs.scala-lang.org/style/types.html) doesn't seem to provide any definitive guidance on this, stating:
Use type inference where possible, but put clarity first, and favour explicitness in public APIs.
To my mind, this is a bit contradictory. While it's clearly obvious what type this variable is:
val tokens = new HashMap[String, Int]
It's not so obvious what type this one is:
val tokens = readTokens()
So, if I was putting clarity first I would probably annotate all variables where the type is not already declared on the same line.
Do any Scala practitioners have guidance on this? Am I crazy to be considering adding type annotations to my local variables? I'm particularly interested in hearing from folks who spend a lot of time reading scala code (for example, in code reviews), as well as writing it.
It's not so obvious what type this one is:
val tokens = readTokens()
Good names are important: the name is plural, ergo it returns some collection of some kind. The most general collection types in Scala are Traversable and Iterator, and they mostly share a common interface, so it's not really important which one of the two it is. The name also talks about "reading tokens", ergo it obviously should return Tokens in some fashion. And last but not least, the method call has parentheses, which according to the style guide means it has side-effects, so I wouldn't count on being able to traverse the collection more than once.
Ergo, the return type is something like
Traversable[Token]
or
Iterator[Token]
and which of the two it is doesn't really matter because their client interfaces are mostly identical.
Note also that the latter constraint (only traversing the collection once) isn't even captured in the type, even if you were providing an explicit type, you would still have to look at the name and the style!

Generating and consuming an array within a StringTemplate-4 template

I'm new to StringTemplate4 and probably I am going to ask something overly simple, impossible or stupid but I couldn't find any other information on it.
So far, I have set this minimal set of templates:
define(name,arity) ::= "<name>(<vars(arity)>)."
vars(n) ::= "<n:var();separator=\", \">"
var(n) ::= "V<n>"
and I would like to get:
pred(V1, V2, V3).
by calling the following code:
STGroup group = new STGroupFile(...);
ST st = group.getInstanceOf("define");
st.add("name", "pred");
st.add("arity", 3);
String result = st.render();
Is it possible? Many thanks in advance.
StringTemplate doesn't have built-in operators for repeating. Instead, you'll need to iterate, like described in the following question.
Is there anything like Enumerable.Range(x,y) in Java?
Keep in mind that you'll need to pass an Iterator<T> and not an Iterable<T> due to a current limitation in StringTemplate (the interpreter supports Collection<T>, but not Iterable<T>). If you want to use the built-in iteration variable i or i0, you could also pass an appropriately sized new Object[n].

Using LuaJ with Scala

I am attempting to use LuaJ with Scala. Most things work (actually all things work if you do them correctly!) but the simple task of setting object values has become incredibly complicated thanks to Scala's setter implementation.
Scala:
class TestObject {
var x: Int = 0
}
Lua:
function myTestFunction(testObject)
testObject.x = 3
end
If I execute the script or line containing this Lua function and pass a coerced instance of TestObject to myTestFunction this causes an error in LuaJ. LuaJ is trying to direct-write the value, and Scala requires you to go through the implicitly-defined setter (with the horrible name x_=, which is not valid Lua so even attempting to call that as a function makes your Lua not parse).
As I said, there are workarounds for this, such as defining your own setter or using the #BeanProperty markup. They just make code that should be easy to write much more complicated:
Lua:
function myTestFunction(testObject)
testObject.setX(testObject, 3)
end
Does anybody know of a way to get luaj to implicitly call the setter for such assignments? Or where I might look in the luaj source code to perhaps implement such a thing?
Thanks!
I must admit that I'm not too familiar with LuaJ, but the first thing that comes to my mind regarding your issue is to wrap the objects within proxy tables to ease interaction with the API. Depending upon what sort of needs you have, this solution may or may not be the best, but it could be a good temporary fix.
local mt = {}
function mt:__index(k)
return self.o[k] -- Define how your getters work here.
end
function mt:__newindex(k, v)
return self.o[k .. '_='](v) -- "object.k_=(v)"
end
local function proxy(o)
return setmetatable({o = o}, mt)
end
-- ...
function myTestFunction(testObject)
testObject = proxy(testObject)
testObject.x = 3
end
I believe this may be the least invasive way to solve your problem. As for modifying LuaJ's source code to better suit your needs, I had a quick look through the documentation and source code and found this, this, and this. My best guess says that line 71 of JavaInstance.java is where you'll find what you need to change, if Scala requires a different way of setting values.
f.set(m_instance, CoerceLuaToJava.coerce(value, f.getType()));
Perhaps you should use the method syntax:
testObject:setX(3)
Note the colon ':' instead of the dot '.' which can be hard to distinguish in some editors.
This has the same effect as the function call:
testObject.setX(testObject, 3)
but is more readable.
It can also be used to call static methods on classes:
luajava.bindClass("java.net.InetAddress"):getLocalHost():getHostName()
The part to the left of the ':' is evaluated once, so a statement such as
x = abc[d+e+f]:foo()
will be evaluated as if it were
local tmp = abc[d+e+f]
x = tmp.foo(tmp)

Updating data in SORM seems possible (even though I was told it aimed at immutable data...)

I was told that SORM aims at immutable data. It's not written on the website - at least not in the main parts I was looking at, so I was a bit surprized of the rigidity of the claim. I was just aware it would recommend to do so. But maybe I was just missing something.
The examples tell you to use a ".copy(propery = newvalue)" before calling a Db.save() on the object. So thats a hint.
I was interrested in what would happen if I would just change the data and update it in the database. Strangely the following just worked fine:
case class Agent( var name : String )
object Db extends Instance(
entities = Set( Entity[Agent]() ),
url = "jdbc:h2:mem:hansi"
)
class SORMTest extends FunSuite {
test("Update") {
// Store values in the db:
val agent = Db.save( Agent("test") )
agent.name = "hansi"
Db.save(agent)
}
It produced an update statement in the database that changed the name property for the corresponding id.
Is it kind of crazy to do so? Any comments from the developers?
I was told that SORM aims at immutable data. It's not written on the website
It's stated plenty of times that SORM strongly follows functional programming idioms. This implies operation on immutable data-structures only.
The examples tell you to use a ".copy(propery = newvalue)" before calling a Db.save() on the object.
That's where you're wrong. The examples tell you to use .copy(..) to get an updated immutable value of the object it's called on, calling it before calling a Db.save() per se as in the following:
agent.copy(name = "new name")
Db.save(agent)
will have absolutely no effect, because, once again, .copy() doesn't mutate the object it's called on, instead it returns an updated copy of this object. So the proper use is the following:
val updatedAgent = agent.copy(name = "new name")
Db.save(updatedAgent)
or simply:
Db.save( agent.copy(name = "new name") )
But the fact is all the above has to do with SORM only as much as it has to do with functional programming in Scala in general. This is really a very basic stuff about how case classes are supposed to be used. So please do yourself a favor and introduce yourself to basics of functional programming. This will wipe out all the questions on SORM you've already had and, I'm sure, plenty of those which are comming up otherwise.
Your example works and it's supposed to, but it doesn't change the fact that it goes against the basic idioms of functional programming and as such is an unidiomatic use of SORM.

What is the difference between = and := in Scala?

What is the difference between = and := in Scala?
I have googled extensively for "scala colon-equals", but was unable to find anything definitive.
= in scala is the actual assignment operator -- it does a handful of specific things that for the most part you don't have control over, such as
Giving a val or var a value when it's created
Changing the value of a var
Changing the value of a field on a class
Making a type alias
Probably others
:= is not a built-in operator -- anyone can overload it and define it to mean whatever they like. The reason people like to use := is because it looks very assignmenty and is used as an assignment operator in other languages.
So, if you're trying to find out what := means in the particular library you're using... my advice is look through the Scaladocs (if they exist) for a method named :=.
from Martin Odersky:
Initially we had colon-equals for assignment—just as in Pascal, Modula, and Ada—and a single equals sign for equality. A lot of programming theorists would argue that that's the right way to do it. Assignment is not equality, and you should therefore use a different symbol for assignment. But then I tried it out with some people coming from Java. The reaction I got was, "Well, this looks like an interesting language. But why do you write colon-equals? What is it?" And I explained that its like that in Pascal. They said, "Now I understand, but I don't understand why you insist on doing that." Then I realized this is not something we wanted to insist on. We didn't want to say, "We have a better language because we write colon-equals instead of equals for assignment." It's a totally minor point, and people can get used to either approach. So we decided to not fight convention in these minor things, when there were other places where we did want to make a difference.
from The Goals of Scala's Design
= performs assignment. := is not defined in the standard library or the language specification. It's a name that is free for other libraries or your code to use, if you wish.
Scala allows for operator overloading, where you can define the behaviour of an operator just like you could write a method.
As in other languages, = is an assignment operator.
The is no standard operator I'm aware of called :=, but could define one with this name. If you see an operator like this, you should check up the documentation of whatever you're looking at, or search for where that operator is defined.
There is a lot you can do with Scala operators. You can essentially make an operator out of virtually any characters you like.