Bypassing deprecation warnings in Scala 2.11 - scala

There is a nice way to avoid deprecation warnings in Scala 2.10 (and before) by invoking the deprecated method from a deprecated local def. Unfortunately, it doesn't work in Scala 2.11. Is there an alternative?

From this Scala issue comment, we can define methods calling deprecated API in a deprecated class/trait, and have the companion object to this class extend it without a warning:
scala> #deprecated("", "") def foo = 0
foo: Int
scala> object Test { #deprecated("", "") class Coral { def fooForwarder = foo }; object Coral extends Coral }
defined object Test
scala> Test.Coral.fooForwarder
res1: Int = 0

Related

Scala: How to define the default value for a constructor parameter within the companion object?

The following Scala code does not compile in the Scala REPL 2.11.6:
object Foo {
val DefaultSize: Int = 10
}
class Foo(size: Int = Foo.DefaultSize)
The compile error is:
value DefaultSize is not a member of object Foo
class Foo(size: Int = Foo.DefaultSize)
Tested with Scala 2.11. This is particularly strange, since it follows exactly the accepted answer (in year 2012) here: Use method return value as default constructor parameter in Scala, which nowadays does not compile, neither. So how to achieve the intended behavior?
As explained in Programming in Scala, this is because the Scala REPL creates a new nested scope for each new statement you type in. This implies your code is interpreted as:
object Foo {
val DefaultSize: Int = 10
}
{
class Foo(size: Int = Foo.DefaultSize)
}
While the same book mentions that both the class and its companion object must be defined in the same source file, it seems that they furthermore must be in the same scope, since the code block above does not compile with scalac.
I know two ways to work around this in the REPL. As mentioned by others, you could enter :paste mode before defining the class and companion object. Alternatively, you could put both into the same scope, e.g., by defining them inside an object:
object My {
object Foo {
val DefaultSize: Int = 10
}
case class Foo(size: Int = Foo.DefaultSize)
}
Now you can use Foo as expected:
scala> new My.Foo()
res0: My.Foo = Foo(10)
scala> new My.Foo(20)
res1: My.Foo = Foo(20)
(I made class Foo a case class to get concise REPL results in the last code block. The answer works without this change, however.)

Is there anyway to create a new Scala object from a Java Class

I have a number of use cases for this, all around the idea of interop between existing Java libraries and new Scala Code. The use case I've selected is the easiest I think.
Use Case:
I working on providing a JUnit Runner for some scala tests (so that I can get my lovely red / green bar in Eclipse)
The runner needs to have a constructor with a java class as a parameter. So in Scala I can do the following:
class MyRunner(val clazz: Class[Any]) extends Runner {
def getDescription(): Description
def run(notifier: RunNotifier)
}
When I use either
#RunWith(MyRunner)
object MyTestObject
or
#RunWith(MyRunner)
class MyTestClass
then the runner is indeed instantiated correctly, and is passed a suitable class object
Unfortunately what i want to do now is to "get hold of" the object MyTestObject, or create a MyTestClass, which are both Scala entities. I would prefer to use Scala Reflection, but I also want to use the standard Junit jar.
What I have done
The following Stackover flow questions were educational, but not the same problem. There were the nearest questions I could find
How to create a TypeTag manually?
Any way to obtain a Java class from a Scala (2.10) type tag or symbol?
Using Scala reflection with Java reflection
The discussion on Environments, Universes and Mirrors in http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html was good, and the similar documents on other scala reflection also helped. Mostly through it is about the Scala reflection.
I browsed the Scaladocs, but my knowledge of Scala reflection wasn't enough (yet) to let me get what I wanted out of them.
Edit:
As asked here is the code of the class that is being created by reflection
#RunWith(classOf[MyRunner])
object Hello2 extends App {
println("starting")
val x= "xxx"
}
So the interesting thing is that the solution proposed below using the field called MODULE$ doesn't print anything and the value of x is null
This solution works fine if you want to use plan old java reflection. Not sure if you can use scala reflection given all you will have is a Class[_] to work with:
object ReflectTest {
import collection.JavaConversions._
def main(args: Array[String]) {
val fooObj = instantiate(MyTestObject.getClass())
println(fooObj.foo)
val fooClass = instantiate(classOf[MyTestClass])
println(fooClass.foo)
}
def instantiate(clazz:Class[_]):Foo = {
val rm = ru.runtimeMirror(clazz.getClassLoader())
val declaredFields = clazz.getDeclaredFields().toList
val obj = declaredFields.find(field => field.getName() == "MODULE$") match{
case Some(modField) => modField.get(clazz)
case None => clazz.newInstance()
}
obj.asInstanceOf[Foo]
}
}
trait Foo{
def foo:String
}
object MyTestObject extends Foo{
def foo = "bar"
}
class MyTestClass extends Foo{
def foo = "baz"
}

scala case class private apply method( repl bug ?)

in Scala2.10.0 REPL
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_13).
Type in expressions to have them evaluated.
Type :help for more information.
scala> case class A private(i:Int)
defined class A
scala> A(1)
res0: A = A(1)
But if compile
$ scala -version
Scala code runner version 2.10.0 -- Copyright 2002-2012, LAMP/EPFL
$ cat Main.scala
package foo
case class A private (i:Int)
object Main extends App{
println(A(1))
}
$ scalac Main.scala
Main.scala:6: error: constructor A in class A cannot be accessed in object Main
println(A(1))
^
one error found
A.apply(1) is compile error.
is this Scala2.10.0 REPL bug?
FYI Scala2.9.2 REPL is following
Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_13).
Type in expressions to have them evaluated.
Type :help for more information.
scala> case class A private(i:Int)
defined class A
scala> A(1)
<console>:10: error: constructor A in class A cannot be accessed in object $iw
A(1)
^
This definitely looks like a REPL bug.
Note that the constructor is correctly marked as private (in other words, new A(1) does not compile, as expected), it is only the factory (A.apply) that is wrongly public.
I see... You think you're calling the constructor when you write A(1). You're not. You're calling the factory added for you in the automatically generated (public) companion object and its public apply method.
Addendum
My day to be repeatedly wrong…
In the 2.10.0 REPL:
scala> object REPL { case class CC1 private(i: Int); val cc1_1 = CC1(23) }
<console>:7: error: constructor CC1 in class CC1 cannot be accessed in object REPL
object REPL { case class CC1 private(i: Int); val cc1_1 = CC1(23) }
The REPL has one huge semantic difference w.r.t. the ordinary compiler.
Consider what it means to be able to do this:
scala> val v1 = 23
v1: Int = 23
scala> val v1 = 42
v1: Int = 42
Could you do that in compiled Scala code? Of course not, it would be a prohibited double definition.
How does the REPL do this? In effect every line you enter is in a progressively more nested scope. The appearance of redefinition is actual shadowing. It's as if you did this:
object REPL1 {
val v1 = 23
object REPL2 {
val v1 = 42
object REPL3 {
// Next REPL line here...
}
}
}
So, how do you get companions? Put an explicit object (or other scope-forming construct) around them. And remember, no blank lines. The REPL will stop accepting input for a given "line" or "block" when you do.

Scala case class constructor with WrappedArray argument

I have the following scenario:
sealed abstract class Type(val inUse: Boolean)
case class IntTy(override val inUse: Boolean) extends Type(inUse)
case class TupleTy(override val inUse: Boolean, elems: Type*) extends Type(inUse) {
def this(elems: Type*) = this(false, elems:_*)
}
In Scala 2.8.0 this works just fine and I can create a new TupleTy instance with:
TupleTy(IntTy(false))
However, I've just updated to Scala 2.9.1 final and it no longer works. I now get the following error:
error: type mismatch;
found : IntTy
required: Boolean
TupleTy(IntTy(false))
^
Is this a bug or am I missing somehing?
I'm not sure that it works in 2.8.0.
You have defined an additional constructor, but not an additional factory method.
new TupleTy(IntTy(false)) // works as expected
EDIT
Here is a possible workaround
case class TupleTy(override val inUse: Boolean = false)(elems: Type*) extends Type(inUse)
Now you can do ugly things like this, but you shouldn't. No really, you shouldn't.
TupleTy()(IntTy(false))
creating your TupleTy with "new" (like with a regular class) works:
scala> new TupleTy(IntTy(false))
res3: TupleTy = TupleTy(false,WrappedArray(IntTy(false)))
additional constructors for case classes need to be called with "new", because (unlike the default constructor) the don't get "translated" to an apply method on the companion object.
Note that the "unapply" does not get generated either, so pattern matching on your TupleTy may not work as intended.
Here's some background discussion on scala-lang.org as to why the scala compiler has not been augmented to handle multiple case class constructors.
EDIT you can create the additional "apply" yourself, if you want:
object TupleTy {
def apply(elems: Type*) = new TupleTy(false, elems:_*)
}
with that, you can do:
scala> TupleTy(IntTy(false))
res4: TupleTy = TupleTy(false,WrappedArray(IntTy(false)))

scala: tracing implicits selection and other code magics

When trying to figure how a library works, implicit conversions are confusing. For example, looking at an expression like 'val foo: Foo = 1', what converts 1 to Foo?
Is it possible to instruct the scala library (or REPL) to print out the code paths that are executing while evaluating an expression?
You can add "-Xprint:typer" to the compiler command line (or "-Ybrowse:typer" for a swing GUI browser) to see the code with the conversions explicitly applied.
As an alternative to printing out the conversions, one must realize implicits can't just come out of the blue. You have to bring them into scope in some way. The alternatives are:
Explicit import statement. Watch out for import x.y._ when y is an object, as this is the only way to bring in an implicit into scope.
The object companion of the class that is being converted into something else.
The object companion of the target class, as long as that target is made explicit somehow (such as in your example).
Note that the object scala.Predef is all imported into scope by default, which is how Scala's default implicits get into scope.
scalac -print prints the code after implicit type conversions where applied.
class A{
val x : String = "hi" drop 1
}
Will result in:
package <empty> {
class A extends java.lang.Object with ScalaObject {
#remote def $tag(): Int = scala.ScalaObject$class.$tag(A.this);
private[this] val x: java.lang.String = _;
<stable> <accessor> def x(): java.lang.String = A.this.x;
def this(): A = {
A.super.this();
A.this.x = scala.this.Predef.forceRandomAccessCharSeq(
scala.this.Predef.stringWrapper("hi").drop(1));
()
}
}
}