What we want is basically this:
/foo/* controllers.FooController.foo
However this doesn't work.
We have found the following workaround:
/foo/*ignore controllers.FooController.foo(ignore)
But this makes the code of the method controllers.FooController.foo slightly ugly. Is there a better way to do this?
Looking at the code over here, the router isn't able to deal with the "slug" part without specifying an identifier... the parser combinator doesn't declare it as optional, and the map (^^) is clearly using it as is.
It could be a good feature request if it wouldn't induce other problems where a pattern will hide all other routes because it's defined higher in the file (or even worst, included).
And it looks like it has been done on purpose if we look here, we can figure out that dynamic parameter cannot be assigned a default value -- indeed, in this case we'll fall in the case I've just mentioned :-/.
My first advice would be to tell you to use ignore as an Option[String] and the action definition to set it as None (rather than an empty String because it's more expressive).
My second would be to incite you to wonder if such case is really relevant, because it's error prone and could hide further problems
Related
I'm using GWT 2.9 with elemental2-1.0.0-RC1.
The following code throws a ClassCastException at runtime:
DocumentRange documentRange = Js.cast(DomGlobal.document); // Fails
Range range = documentRange.createRange(); // Never reaches here
When I change to use an Js.uncheckedCast() instead, it succeeds:
DocumentRange documentRange = Js.uncheckedCast(DomGlobal.document);
Range range = documentRange.createRange(); // Works
The documentation for Js.uncheckedCast() says:
"You should always prefer regular casting over this (unless you know what you are doing!)."
I don't know why I'm having to use it, so I'm feeling nervous. Can someone explain how Js.cast() performs its type-checking and why I need to use an Js.uncheckedCast() in this instance?
Js.cast() is a way to cheat a bit, and do something that the Java language will not permit, but might actually be legal. Ignoring "how it actually works", the idea is that you can now get past issues where Java would complain, even if it turns out to be legit.
An example could be where you take a java.lang.Double or double and want to treat it as a JsNumber so you can call toPrecision(2) on it. Since java.lang.Double is final, it isn't legal to cast to an unrelated type, but Java doesn't know that in GWT, Double is really just a js Number. So, instead you can perform the cast with Js.cast(). The compiler will insert a runtime type check in there, verifying at runtime that your number is in fact a JS Number instance.
Another example could be trying to extend some native type that elemental2 provides, either to implement a workaround for a missing feature, or to do something browser-specific. Your new class may not extend the existing class - from JS's perspective this is okay, you are just describing the API that you know will exist at runtime. As such, we need to avoid the Java language check of "does this cast even make sense?", and just tell the compiler to try it.
On the other hand, you can "lie" to the compiler with Js.uncheckedCast(). This is used in cases where you are even asking the runtime to skip the check, and just pretend that it will work. This can let you do weird things, like treating Strings as if they were arrays, or solve cross-frame problems. No runtime check will be emitted, so instead you might just get a TypeError if a method/property is missing, instead of a proper ClassCastException.
In elemental2-dom 1.0.0-RC1, there is a class called DocumentRange, but it doesnt really make any sense - it is declared as a class, which means it can be type checked in JS, but the browser spec says that it should be an "interface" (which in JS-land means that it just is a description of a type, rather than something you can typecheck). https://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level2-DocumentRange-method-createRange
This bug is inherited from closure-compiler, which claims that this has a constructor: https://github.com/google/closure-compiler/blob/6a418aa/externs/browser/w3c_range.js#L241-L251
The fix is for closure-compiler to refer to this as an interface, and for a new release of elemental2 to be made so you can use this.
There are two workarounds you can make here. The first is to cheat with Js.uncheckedCast(DomGlobal.document) and say "yes, I know that the Document is not instanceof DocumentRange, but that's because there is no such class as DocumentRange, so just pretend it worked so I can call createRange() on it". This is what you are doing already - it hides the fact there is a bug, but at the end of the day it works.
The "correct" answer is to declare your own DocumentRange, and do a Js.cast() to that instead. This is still gross - you have to keep your new interface around until closure gets fixed, and then elemental2 gets released, and then you have to remember to clean it up.
In this case, I would suggest lying to GWT and using Js.uncheckedCast() - there is only a single method on here, and it is unlikely to change in a meaningful way.
I'm attempting to parse json from the GitHub API with play-json, and encountering a problem with the merge_commit_sha field on Pull Requests (incidentally, I know this field is deprecated, but don't want to discuss that in this parsing problem!). Unfortunately merge_commit_sha field comes back as the empty string in some cases:
"merge_commit_sha": ""
This is how the field is declared in my case class:
merge_commit_sha: Option[ObjectId],
I have an implicit Format[ObjectId], which does not tolerate the empty string, because that's not a valid value for a Git hash id. I'm also using a play-json macro-generated Read[PullRequest], which I'd like to keep on using, in preference to individually declaring reads for every single field on pull requests.
As I've declared the field to be an Option, I'd like "merge_commit_sha": "" to be read as the value None, but this is not what currently happens - a string is present, so the Format[ObjectId] is invoked, and returns a JsFailure.
One thing I tried was declaring an implicit Format[Option[ObjectId]] with the required behaviour, but it didn't seem to get used by the macro-generated Read[PullRequest].
You can define a custom Reads and Writes yourself.
Using Json.format[MyType] uses a Scala macro. You may be able to hook into that. Although, 'extending' a macro for this one case class just seems wrong.
Custom Reads and Writes might be a little 'boilerplate-like' and boring, but they have their upsides.
For example if your json has a bunch of new fields on it, you wont get a JsError when validating or transforming it to a case class. You only take what you need from the JSON and create objects. It also allows for a separation between your internal model and what you're consuming, which in some cases is preferred.
I hope this helps,
Rhys
EDIT
After using some other JSON libs I may have found what you are looking for.
I know the question was asking specifically after Play JSON.
If you're able to move away from Play JSON, Look at spray-json-shapeless specifically JsNullBehaviour and JsNullNotNone REF.
With intellij idea, how do I find out what makes a variable be visible?
An example of when it is hard:
Suppose you look at class A, and you see a variable something. If you jump to source you see that it's defined in trait X. But you don't extend trait X directly. What do you extend, then, that makes this variable visible? If you have a deeply nested hierarchy, tracking can be hard.
Any recommendations or solutions?
EDIT: Please vote for the feature if you're interested: http://youtrack.jetbrains.com/issue/IDEA-124369
I don't think that IntelliJ IDEA has any shortcut for "finding what makes a variable visible".
However you can determine it using the "Find Usages" option (Alt + F7). For example:
import java.nio._
object TempObj extends App {
def func = 2
val p = file.Paths.get("some-path")
func
}
So Find Usages on "file", tells you that its from the Package "file" (in heading of the new Tab it also shows the complete package name, ex: Find Usages of java.nio.file in Project Files).
Whereas Find Usages on func will tell you that its a Method (And the Tab heading now says: Find Usages of func() in Project and Libraries)
So now in way you can determine, what exactly makes the variable visible. This also works for imports since it shows the package from which it is imported and you can then look for import of that packages.
I know of two almost-solutions to this problem.
Go-to-declaration, as you mentioned, solves this problem in the case of local variables.
More generally, the "find usages" feature gives you a neat little breakdown by type and file of different uses of the variable. From this you can see if it's involved in a static import.
It's not perfect, but with a moment's thought these two are generally sufficient to figure out what you want.
Use ctrl+b or F4 to jump to source code. Alternatively you can use ctrl+shift+a to get option/action. You can find shortcuts at http://gaerfield.github.io/ide-shortcuts/ as well. Hope it will help.
From what I understood you want to see the code that creates an Object you use, for instance Mystery someMystery;.
That gives you two options to populate someMystery:
someMystery = ... where ... is your code to populate
someMystery and if that is the case you should follow
that code (with ctrl+B as far as you need to) to the point where it
actually creates the Mystery object.
Use CDI to populate that object instance for you, in which case you should look into the CDI mechanism in order to see in what way the object instance is populated.
In either way IMO there is no way to know for sure if the someMystery instance is of some more concrete class than Mystery, because it is decided in runtime, not in compile time, so your next bet would be to run the program in debug and see what object goes into someMystery, although you are not guaranteed to get the same type of object every time.
PS. My answer is based entirely on my java understanding of the topic, can't say if it is valid for scala also.
This might not be exactly the answer you were hoping to get.
However, quoting yourself,
If you have a deeply nested hierarchy, tracking can be hard.
Have you considered using composition over inheritance? Perhaps this would remove the need for the feature you are looking for.
Deeply nested hierarchy doesn't sound good. I understand your pain about that.
When you override vals or defs there is a little circle next to the line number that shows where it is from even when it is from nested hierarchy. Hovering over vals with the command key down also shows you a little tooltip where it is from.
Does this help?
https://youtu.be/r3D9axSlBo8
if you want class, field or method to be visible, you need to implement them as public. If it was your question.
I've read some documentation and downloaded samples but I still got a question.
In most sample, the GIN module uses something like :
bind(MainActivityMapper.class);
bind(VerticalMasterActivityMapper.class);
I don't understand what it does? If I remove it from the sample code, everything works perfectly.
Thanks for any answer.
Someone pointed me to the GUICE page : http://google-guice.googlecode.com/git/javadoc/com/google/inject/Binder.html
There is no reason for it to be different in Gin.
Here is what it says for this particular case :
This statement does essentially nothing; it "binds the
class to itself" and does not change Guice's default behavior. You may
still want to use this if you prefer your Module class to serve as an
explicit manifest for the services it provides. Also, in rare cases,
Guice may be unable to validate a binding at injector creation time
unless it is given explicitly.
Note: I'm not sure wether or not I should Accept my own answer, so I'll leave it as is.
...and why has the package this misleading name (I assumed it had something to do with JavaME or mobile/smart phones)?
I found no references on the internet about scala.mobile.Code or scala.mobile.Location at all nor did I manage to do anything with those classes except getting ClassCastExcetions or NoSuchMethodErrors.
Actually there is not even a single test against scala.mobile in the Scala's test tree which could help understanding that code.
The classes really smell like they were forgotten in the source tree a long time ago and got accidentally released since that.
Maybe I just missed something about them?
Update:
scala.mobile was removed in Scala 2.9.
I just checked the source code.
When Scala changed the name mangling of class files a few years ago and it seems people forgot to update these classes accordingly.
So my answer would be:
At least Location has no purpose, because it is not possible to get anything sensible out of it (except exceptions) and Code without Location is severely limited. It works though if you pass the class literal to Code directly:
import scala.mobile._
val c = new Code(classOf[scala.collection.mutable.StringBuilder])
c.apply[StringBuilder, String]("append")("Foo")
c.apply[String]("toString")() // returns "Foo"
c.apply[Int]("length")() // returns 3
Looks like yet-another implementation in the standard library of reflection-slightly-nicer.
The description of Location pretty much explains what that is about:
The class Location provides a create method to instantiate objects
from a network location by specifying the URL address of the jar/class file.
It might be used by remote actors. Maybe.
As for why it has this misleading name? Well, back in 2004 smart phones had really low penetration, so maybe the association wasn't all that strong.