Is there a way to access constants of a (java) class by an alias in scala? - scala

I would like to make a short alias for a java class.
Is there a way to import (or make a type alias to) a java class (e.g. HttpServletResponse), and access its constant values (e.g. HttpServletResponse) using the alias?
Type alias works fine, but I cannot find a way to access the constants of the class.
EDIT:
I'm sorry I asked a wrong question. I knew importing with a short name works.
What I like to do is avoid writing import ...{HttpServletResponse => Response} every file in which MyHttpServlet is mixed-in.
Type aliases in MyHttpServlet makes it possible without importing, but accessing constants is still the issue. (or maybe it's impossible?)
trait MyHttpServlet extends HttpServlet {
import javax.servlet.http.HttpServletResponse
// works
type Response = HttpServletResponse
// compile error: object creation impossible, since it has 36 unimplemented members.
//object Response extends HttpServletResponse
def notAllowed(response: Response): Unit = {
// works
response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED)
// I would like to do something like this
//response.setStatus(Response.SC_METHOD_NOT_ALLOWED)
}
}

Just rename the import.
import javax.servlet.http.{HttpServletResponse => Response}
response.setStatus(Response.SC_METHOD_NOT_ALLOWED)
Type aliases don't allow static member access because one can't call members on a type in scala, it is only possible on values.

Related

Is it possible to automatically load an implicit def if included as a dependency (no importing)

I'm working on a commons library that includes a config library (https://github.com/kxbmap/configs).
This config library uses "kebab-case" when parsing configuration files by default and it can be overridden by an implicit def in scope.
However, I don't want to force that on the users of my commons library when they get access to the config library transitively.
So without me forcing users to import this implicit, like:
import CommonsConfig._
can I somehow override the naming strategy via an implicit that gets into scope by only including my commons library on the classpath. I'm guessing no but I just have to ask :)
So if not, is someone aware of another approach?
kxbmap/configs isn't that well documented to explain this.
Thanks!
Implicits work in compile time, so they cannot get magically present if something is included and then disappear if it isn't.
The closest thing would be something like:
main library
package my.library
// classes, traits, objects but no package object
extension
package my
package object library {
// implicits
}
user's code
import my.library._
however that would only work if there were no package object in main library, only one extension library could pull off this trick at once (Scala doesn't like more than one package object) and user would have to import everything available with a package, always.
In theory you could create a wrapper around all you deps, with your own configs:
final case class MyLibConfig(configsCfg: DerivationConfig)
object MyLibConfig {
implicit val default: MyLibConfig = ...
}
and then derive using this wrapper
def parseThings(args...)(implicit myLibConfig: MyLibConfig) = {
implicit val config: DerivationConfig = myLibConfig.config
// derivation
}
but in practice it would not work (parseThings would have to already know the target type or would need to have the already derived implicits passed). Unless you are up to writing your own derivation methods... avoid it.
Some way of making user just import all relevant stuff is the most maintainable strategy. E.g. you could pull off the same thing authors did and add type aliases for all types that you use, do the same for companion objects and finally put some implicits there:
package my
package object library {
type MyType = some.library.Type
val MyType = some.library.Type
implicit val derivationConfig: DerivationConfig = ...
}

Why does Scala place a dollar sign at the end of class names?

In Scala when you query an object for either its class or its class name, you'll get a rogue dollar sign ("$") at the tail end of the printout:
object DollarExample {
def main(args : Array[String]) : Unit = {
printClass()
}
def printClass() {
println(s"The class is ${getClass}")
println(s"The class name is ${getClass.getName}")
}
}
This results with:
The class is class com.me.myorg.example.DollarExample$
The class name is com.me.myorg.example.DollarExample$
Sure, it's simple enough to manually remove the "$" at the end, but I'm wondering:
Why is it there?; and
Is there anyway to "configure Scala" to omit it?
What you are seeing here is caused by the fact that scalac compiles every object to two JVM classes. The one with the $ at the end is actually the real singleton class implementing the actual logic, possibly inheriting from other classes and/or traits. The one without the $ is a class containing static forwarder methods. That's mosty for Java interop's sake I assume. And also because you actually need a way to create static methods in scala, because if you want to run a program on the JVM, you need a public static void main(String[] args) method as an entry point.
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)
object Main { def main(args: Array[String]): Unit = ??? }
// Exiting paste mode, now interpreting.
scala> :javap -p -filter Main
Compiled from "<pastie>"
public final class Main {
public static void main(java.lang.String[]);
}
scala> :javap -p -filter Main$
Compiled from "<pastie>"
public final class Main$ {
public static Main$ MODULE$;
public static {};
public void main(java.lang.String[]);
private Main$();
}
I don't think there's anything you can do about this.
Although all answer that mention the Java reflection mechanism are correct this still doesnot solve the problem with the $ sign or the ".type" at the end of the class name.
You can bypass the problem of the reflection with the Scala classOf function.
Example:
println(classOf[Int].getSimpleName)
println(classOf[Seq[Int]].getCanonicalName)
=> int
=> scala.collection.Seq
=> Seq
With this you just have the same result as you have in for example Java
There are several problems with your approach:
You are using Java Reflection. Java Reflection doesn't know anything about Scala.
Furthermore, you are using Java Reflection on a Singleton Object, a concept that doesn't even exist in Java.
Lastly, you are using Java Reflection to ask for the class of a Singleton Object, but in Scala, Singleton Objects aren't instances of a class.
So, in other words: you are asking the wrong language's reflection library to reflect on something it doesn't understand and return something that doesn't even exist. No wonder you are getting nonsense results!
If you use Scala Reflection instead, the results become a lot more sensible:
import scala.reflect.runtime.{universe => ru}
def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
object Foo
val theType = getTypeTag(Foo).tpe
//=> theType: reflect.runtime.universe.Type = Foo.type
As you can see, Scala Reflection returns the correct type for Foo, namely the singleton type (another thing that doesn't exist in Java) Foo.type.
In general, whereas Java Reflection deals mainly in classes, Scala Reflection deals in Types.
Using Scala Reflection instead of Java Reflection is not only better because Java Reflection simply doesn't understand Scala whereas Scala Reflection does (in fact, Scala Reflection is actually just a different interface for calling into the compiler, which means that Scala Reflection knows everything the compiler does), it also has the added benefit that it works on all implementations of Scala, whereas your code would break on Scala.js and Scala-native, which simply don't have Java Reflection.
This is a result of compiling to the JVM. To make an object in scala requires two classes. The "base" class and the class to make the singleton object. Because these classes can't both have the same name, the $ is appended. You could probably modify the compiler so that it won't make a $ but you will still need some way to name the generated class names.

How to (properly) enrich the standard library?

I would like to define an implicit conversion from Iterator[T] to a class that I have defined: ProactiveIterator[A].
The question isn't really how to do it but how to do it properly, i.e. where to place the method, so that it is as transparent and unobtrusive as possible. Ideally it should be as the implicit conversion from String to StringOps in scala.Predef If the conversion was from a class in the library to some other class, then it could be defined inside that class, but AFAIK that's not possible here.
So far I have considered to add an object containing these conversions, similarly to JavaConversions, but better options may be possible.
You don't really have much of a choice. All implicits must be contained within some sort of object, and imported with a wildcard import (you could import them individually, but I doubt you want that).
So you'll have some sort of implicits object:
package foo.bar
object Implicits {
implicit class ProactiveIterator[A](i: Iterator[A]) {
...
}
}
Then you must explicitly import it wherever you use it:
import foo.bar.Implicits._
In my opinion, this is a good thing. Someone reading the code might not understand where your pimped methods are coming from, so the explicit import is very helpful.
You can similarly place your implicits within a package object. You would have to import them the same way into other namespaces, but they would be available to classes within the same package.
For example, using the following, anything within foo.bar will have this implicit class available:
package foo
package object bar {
implicit class ProactiveIterator[A](i: Iterator[A]) {
...
}
}
Elsewhere you would import foo.bar._ (which may or may not be as clean, depending on what's in bar).

Use function without explicit import in Scala

I like Scala's sys.error function - but I want to distinguish two cases: internal errors (e.g. database problem) and user errors (invalid input).
I tried extending Scala - but it doesn't seem to work:
package scala
class UserException(msg: String) extends RuntimeException(msg)
package object err {
def internal(message: String): Nothing =
sys.error(message)
def usr(message: String): Nothing =
throw new UserException(message)
}
How should I define err.usr() to be able to use it without an explicit import?
You can't, only scala.Predef is imported by default and it's not user extensible in any useful way.
You could put these definitions on the package object of your package hierarchy. Then, everything on that package will see them without import.

In Scala, how can I define a companion object for a class defined in Java?

I'd like to add implicit conversions to Java classes generated by a modeling tool. So I want to add them to the companion object of those classes, so that the compiler automatically finds them. But I cannot add them in a separate file, because the companion has to be defined in the same file. Is there anything I can do about this?
Of course, I can define all my implicit conversions in another object and then bring it into scope, but this requires an extra import. Any other solution?
You can define your own companion object of course, which I often do in my own project-specific Predef-like arrangement. For example:
object domain {
type TimeUnit = java.util.concurrent.TimeUnit
object TimeUnit {
def valueOf(s : String) = java.util.concurrent.TimeUnit.valueOf(str)
val Millis = java.util.concurrent.TimeUnit.MILLISECONDS
//etc
}
Then this can be used:
import my.domain._
val tu : TimeUnit = TimeUnit.valueOf("MILLISECONDS")
But your domain.TimeUnit is a module (i.e. scala object)
With the Scala compiler as it stands now there is no way to define companion objects other than by putting them in the same file. The best you can do is a non-companion object with the same package and name and an extra import.
If you can think of a good way to create post-hoc companionship without breaking assumptions about encapsulation please come post on http://groups.google.com/group/scala-debate because it would clearly be a very useful feature.