How to convert a scala.xml.Elem into a JsExp in Lift? - scala

My latest problem is one that I already have a solution for, it just
feels like there should be a better way.
The problem:
I want to send a PartialUpdate to a comet service, and I need to XML
escape the string, so that when it is used on the client it gets the
correct results. I currently have:
override def lowPriority = {
case v: List[TaskOwner] => {
partialUpdate(
taskOwners.foldLeft(JsCrVar("table", Call("$", Str("table#userTable"))) &
Call("table.dataTable().fnClearTable"))((r, c) => {
r & Call("table.dataTable().fnAddData",
JsArray(Str(Text(c.name).toString),
Str(Text(c.initials).toString),
Str(makeDeleteButton(c).toString)),
Num(0))
}) & Call("table.dataTable().fnDraw"))
}
}
And this works fine, however the Str(Text(c.name).toString) feels
quite wordy to me. Now, I can, of course, create a pair of implicit
conversion functions for this, but it seems like this should have
already been done somewhere, I just don't know where. And so, in the
spirit of reducing the code that I have written, I ask if anyone knows
a better way to do this, or if the implicit conversion already exist
somewhere?
I have seen reference to a solution here. However the code is summarized as:
def xmlToJson(xml: Elem): JsExp = {
// code to map XML responses to JSON responses. Handles tricky things like always returning
// js arrays for some fields even if only 1 element appears in the XML
}

A possibly better way of escaping the names is, instead of:
JsArray(Str(Text(c.name).toString),
Str(Text(c.initials).toString),
Str(makeDeleteButton(c).toString))
to use
JsArray(Str(c.name.asHtml.toString),
Str(c.initials.asHtml.toString),
Str(makeDeleteButton(c).toString))
This can be further reduced by using an implicit within the class like:
implicit def elemToJsExp(elem: NodeSeq): JsExp = Str(elem.toString)
…
JsArray(c.name.asHtml,
c.initials.asHtml,
makeDeleteButton (c))

I don't know what Str does, but maybe you mean Str(xml.Utility.escape(c.name))?
Well, how about:
def JsStrArray(strings: String*) = JsArray(strings map xml.Utility.escape map Str : _*)
And then just use
JsStrArray(c.name, c.initials, makeDeleteButton(c).toString)
Mmmmm. It might incorrectly escape the result of makeDeleteButton. Anyway, you can play with it and see what looks good.

Related

How to design abstract classes if methods don't have the exact same signature?

This is a "real life" OO design question. I am working with Scala, and interested in specific Scala solutions, but I'm definitely open to hear generic thoughts.
I am implementing a branch-and-bound combinatorial optimization program. The algorithm itself is pretty easy to implement. For each different problem we just need to implement a class that contains information about what are the allowed neighbor states for the search, how to calculate the cost, and then potentially what is the lower bound, etc...
I also want to be able to experiment with different data structures. For instance, one way to store a logic formula is using a simple list of lists of integers. This represents a set of clauses, each integer a literal. We can have a much better performance though if we do something like a "two-literal watch list", and store some extra information about the formula in general.
That all would mean something like this
object BnBSolver[S<:BnBState]{
def solve(states: Seq[S], best_state:Option[S]): Option[S] = if (states.isEmpty) best_state else
val next_state = states.head
/* compare to best state, etc... */
val new_states = new_branches ++ states.tail
solve(new_states, new_best_state)
}
class BnBState[F<:Formula](clauses:F, assigned_variables) {
def cost: Int
def branches: Seq[BnBState] = {
val ll = clauses.pick_variable
List(
BnBState(clauses.assign(ll), ll :: assigned_variables),
BnBState(clauses.assign(-ll), -ll :: assigned_variables)
)
}
}
case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
def assign(ll: Int) :F =
Formula(clauses.filterNot(_ contains ll)
.map(_.filterNot(_==-ll))))
}
Hopefully this is not too crazy, wrong or confusing. The whole issue here is that this assign method from a formula would usually take just the current literal that is going to be assigned. In the case of two-literal watch lists, though, you are doing some lazy thing that requires you to know later what literals have been previously assigned.
One way to fix this is you just keep this list of previously assigned literals in the data structure, maybe as a private thing. Make it a self-standing lazy data structure. But this list of the previous assignments is actually something that may be naturally available by whoever is using the Formula class. So it makes sense to allow whoever is using it to just provide the list every time you assign, if necessary.
The problem here is that we cannot now have an abstract Formula class that just declares a assign(ll:Int):Formula. In the normal case this is OK, but if this is a two-literal watch list Formula, it is actually an assign(literal: Int, previous_assignments: Seq[Int]).
From the point of view of the classes using it, it is kind of OK. But then how do we write generic code that can take all these different versions of Formula? Because of the drastic signature change, it cannot simply be an abstract method. We could maybe force the user to always provide the full assigned variables, but then this is a kind of a lie too. What to do?
The idea is the watch list class just becomes a kind of regular assign(Int) class if I write down some kind of adapter method that knows where to take the previous assignments from... I am thinking maybe with implicit we can cook something up.
I'll try to make my answer a bit general, since I'm not convinced I'm completely following what you are trying to do. Anyway...
Generally, the first thought should be to accept a common super-class as a parameter. Obviously that won't work with Int and Seq[Int].
You could just have two methods; have one call the other. For instance just wrap an Int into a Seq[Int] with one element and pass that to the other method.
You can also wrap the parameter in some custom class, e.g.
class Assignment {
...
}
def int2Assignment(n: Int): Assignment = ...
def seq2Assignment(s: Seq[Int]): Assignment = ...
case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
def assign(ll: Assignment) :F = ...
}
And of course you would have the option to make those conversion methods implicit so that callers just have to import them, not call them explicitly.
Lastly, you could do this with a typeclass:
trait Assigner[A] {
...
}
implicit val intAssigner = new Assigner[Int] {
...
}
implicit val seqAssigner = new Assigner[Seq[Int]] {
...
}
case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
def assign[A : Assigner](ll: A) :F = ...
}
You could also make that type parameter at the class level:
case class Formula[A:Assigner,F<:Formula[A,F]](clauses:List[List[Int]]) {
def assign(ll: A) :F = ...
}
Which one of these paths is best is up to preference and how it might fit in with the rest of the code.

Difference between Future[Any] and Future[_]

Okay, I guess question is already complete in the title.
Nothing big, but I am just wondering. I have a method which returns either a correct value or an error code enum item. For example something like this:
def doMyStuff(): Future[_] = {
val result = db.queryMyData().map {
case some(data) =>
val modifiedData = data.doStuff()
modifiedData
case None =>
Errors.THIS_IS_FALSE
}
result
}
Where db.queryMyData() returns a Future, and data.doStuff() just modifies the data.
Now I have intuitively written Future[_], cause the return value is flexible. But when looking in other libraries I've seen Future[Any] used. Which seems to be logic too, when you use a match-case on the return of the function to check which data it is.
The code which uses that is for example something like this:
doMyStuff().map {
case data: MyDataType => // Blah blah
case Errors.Value => // error handling
}
So, my questions is: What's the difference between the use of Any or _ here, and why should I use the correct one?
It is a matter of semantics:
The Existential TypeT[_] means there is a class/type at the position of _ for which I do not care at all but it must be there.
T[Any] means there has to be a subclass Any present.
The difference comes into play when you want to serialize the underlying class.
If you just use _ without any typebounds you will not be able to use some of the many Scala JSON libraries.

Scala - non-generic wrapper for generic classes

Let's say I have a case class
case class Foo[T<:Bar[T]](t:T)
And I have a
case class FooWrapper[T<:Bar[T]](foos:Seq[Foo[T]])
So far, so good.
Unfortunately, I now want to merge two FooWrapprs in an environment where I have no access to the T used to construct them. I.e. attempting something like this:
def merge(fw1:FooWrapper,fw2:FooWrapper) = {
FooWrapper(fw1.foos ++ fw2.foos)
}
Obviously, the T used to construct fw1,fw2 could be different, which is why this merge fails.
Perhaps I'm just too tired to see the obvious, but what would be the proper way to overcome this limitation? Would having the wrapper class itself implement a merge method work or can I forget about that due to type erasure?
EDIT
I would like a merge method like this:
case class FooWrapper[T<:Bar[T]](foos:Seq[Foo[T]]){
def merge(other:FooWrapper[T]) = FooWrapper[T](this.foos ++ other.foos)
}
And then
def doSomethingWith(w1:FooWrapper,w2:FooWrapper) ={
w1.merge(w2)
}
This compiles fine and just might work, but I'm not sure I can rely on its working correctly.
You can enforce the equivalence of the types of the fw1 and fw2 like this:
def merge[T](fw1:FooWrapper[T],fw2:FooWrapper[T]) = {
FooWrapper[T](fw1.foos ++ fw2.foos)
}
Otherwise, please specify what type do you expect as the result of the merge method?

Blacklist some method calls with Scala Compiler plugin

I wanted to create a scala compiler plugin that would prevents the call of some functions. For example System.exit.
The idea behind the scene is to let people write Scala scripts that would be interpreted on the fly. But I want to ensure that some dangerous actions are prohibited - the way it is done can definitely be discussed.
I started with the example in http://www.scala-lang.org/node/140 and started to replace the Apply section.
Doing some pattern matching I was able to extract a ClassSymbol for the right part of the compilation unit.
Then I wanted to do something like in the example that would be like:
classSymbol.tpe =:= global.typeOf[System]
unfortunately they don't match I get System.type on one side and System on the other.
Of course I could compare String values but I think that there is perhaps a nicer way to achieve this.
Has anyone any advice ?
Just in case a larger part of the code:
def apply(unit: global.CompilationUnit) {
for (global.Apply(fun, _) <- unit.body) {
fun.symbol match {
case method: global.MethodSymbol =>
val classSymbol = method.owner
println(classSymbol.fullName)
println(classSymbol.tpe =:= global.typeOf[System])
case _ => ()
}
}
Perhaps,
val jls = global.findMemberFromRoot(TermName("java.lang.System"))

Scala match/compare enumerations

I have an enumeration that I want to use in pattern matches in an actor. I'm not getting what i'd expect and, now, I'm suspecting I'm missing something simple.
My enumeration,
object Ops extends Enumeration {
val Create = Value("create")
val Delete = Value("delete")
}
Then, I create an Ops from a String:
val op = Ops.valueOf("create")
Inside my match, I have:
case (Ops.Create, ...)
But Ops.Create doesn't seem to equal ops.valueOf("create")
The former is just an atom 'create' and the later is Some(create)
Hopefully, this is enough info for someone to tell me what I'm missing...
Thanks
If you are just trying to get a copy of Create, then you should refer to it directly in your code:
val op = Ops.Create
But if you are parsing it from a string, the string might contain junk, so valueOf returns an Option:
val op1 = Ops.valueOf("create") // Some(Ops.Create)
val op2 = Ops.valueOf("delete") // Some(Ops.Delete)
val op3 = Ops.valueOf("aljeaw") // None
Now, in your match you can just carry along the Option[Ops.Value] and look for:
case(Some(Ops.Create),...)
and you have built-in robustness to junk as input.
Enumeration.valueOf returns None or Some, because you may be asking to create a value that doesn't exist. In your case, for example, Ops.valueOf("blah") would return None, since you don't have an appropriate enumeration value.
To be honest, in this case, I'd use a case class or a case object instead of an Enumeration (they provide better type safety).
It looks like I needed to use the 'get' method of the returned Some to actually get what I wanted. E.g.
ops.valueOf("create").get == Ops.Create
Seems neither intuitive nor friendly but it works.