How can I access args from trait? - scala

The following code:
trait TestMainArgs extends App {
println(s"args are: $args") // I need to have a generic main in trait which refers to args...
}
object MyRealMainObj extends TestMainArgs {
// I do not want to call the generic main from objects this would mean I would need to call them from every object which extendfs TestMainArgs
}
prints:
args are: null
While the following:
trait TestMainArgs extends App {
}
object MyRealMainObj extends TestMainArgs {
println(s"args are: $args")
}
prints:
args are: [Ljava.lang.String;#f82f98
So how can I access args from the trait?
I want to put the logic of the "main" only in the super trait and I don't want code duplication like calling from every object which extends app the super main, is there any way to achieve that?

Another option that is also deprecated is to override main:
trait TestMainArgs extends App {
override def main(args: Array[String]) {
println(s"args are: ${args(0)} from test")
super.main(args)
}
}
The problem is that the way traits are compiled, the constructor is triggered before the main object, which is where args is set. There appears to be no non-deprecated means to do this...

The answer lies in looking at both DelayedInit and App in the Scala source. The real gem lies in the doc comment at the start of DelayedInit:
Example:
* {{{
* trait Helper extends DelayedInit {
* def delayedInit(body: => Unit) = {
* println("dummy text, printed before initialization of C")
* body // evaluates the initialization code of C
* }
* }
*
* class C extends Helper {
* println("this is the initialization code of C")
* }
*
* object Test extends App {
* val c = new C
* }
* }}}
*
* Should result in the following being printed:
* {{{
* dummy text, printed before initialization of C
* this is the initialization code of C
* }}}
So, just extend DelayedInit, follow the warnings you see in App (specifically, don't override args in your extending class), and you should be able to access them just as App does:
#deprecatedOverriding("main should not be overridden", "2.11.0")
def main(args: Array[String]) = {
this._args = args
//other stuff goes here as you like
}
However, if you do it like this, be aware that it is deprecated, like it says there, so you run the risk of losing the functionality in future versions of Scala.

Related

Can Kotlin allow a function that returns a value of this interface's implementation's type?

I want to write something like this:
/**
* Represents a state, large or small.
*/
interface State {
/**
*
*/
val changeValue: StateChange<This> // does not compile; "This" is a keyword I made up that might reference the implementing class
}
/**
* Represents a change in a state, large or small.
*
* #param StateType The type of state that has changed
*/
interface StateChange<StateType: State>
However, as noted in my comment, I don't know the syntax for this. Is that in existance? Or must I use workarounds like forcing a State to take in itself as a generic parameter?
In case it's not apparent, I can't use val changeValue: StateChange<State> because then that makes this possible, and I don't want that:
// BAD EXAMPLE - This is what I want to avoid
class Foo: State { val changeValue: StateChange<Bar> = Bar().changeValue }
class Bar: State { val changeValue: StateChange<Foo> = Foo().changeValue }
You can use a class with a recursive upper bound for this:
interface State<T : State<T>> {
val changeValue: StateChange<T>
}
interface StateChange<StateType: State<StateType>>
Now this code will no longer compile:
class Foo: State<Foo> { val changeValue: StateChange<Bar> = Bar().changeValue }
class Bar: State<Bar> { val changeValue: StateChange<Foo> = Foo().changeValue }

scala App class DelayedInit hook

trait App extends DelayedInit {
//...
private val initCode = new ListBuffer[() => Unit]
/** The init hook. This saves all initialization code for execution within `main`.
* This method is normally never called directly from user code.
* Instead it is called as compiler-generated code for those classes and objects
* (but not traits) that inherit from the `DelayedInit` trait and that do not
* themselves define a `delayedInit` method.
* #param body the initialization code to be stored for later execution
*/
override def delayedInit(body: => Unit) {
initCode += (() => body)
}
//...
}
object CircuitMain extends App {
// You can write tests either here, or better in the test class CircuitSuite.
Circuit.andGateExample //line in question ?
}
Related Post why-if-i-extend-the-app-trait-in-scala-i-override-the-main-method
I can see that in the comment it is saying it will be called by compiler generated code.
and from the related post, it is saying that the scala compiler will do special things about DelayedInit, what made this DelayedInit trait so special ? is it language related feature? or we can do similar things to other traits as well ? if yes, how to do that.
Was pondering this myself the other day...
Yes, it's a language specific feature - check Section 5.1 "Delayed Initializaton" in the Scala Language Specification:
http://www.scala-lang.org/docu/files/ScalaReference.pdf
You can also confirm this checking out the compiler source code:
https://github.com/scala/scala/blob/946b76ad8b31b1fd74e2f8e1972c4a9159ac690a/src/reflect/scala/reflect/internal/StdNames.scala
// Compiler utilized names
...
val delayedInit: NameType = "delayedInit"
val delayedInitArg: NameType = "delayedInit$body"
And also:
https://github.com/scala/scala/blob/96df73d994097e3318d003ddef00194b711289a3/src/reflect/scala/reflect/internal/Definitions.scala
// classes with special meanings
lazy val StringAddClass = requiredClass[scala.runtime.StringAdd]
lazy val ScalaNumberClass = requiredClass[scala.math.ScalaNumber]
lazy val TraitSetterAnnotationClass = requiredClass[scala.runtime.TraitSetter]
lazy val DelayedInitClass = requiredClass[scala.DelayedInit]
def delayedInitMethod = getMemberMethod(DelayedInitClass, nme.delayedInit)

Delaying trait initialization

I need a smart mechanism for component composition which allows mixed in traits to initialize after the composed component. The following throws a NullPointerException:
class Component {
def addListener(pf: PartialFunction[Any, Unit]) {}
}
trait DynamicComponent {
protected def component: Component
component.addListener {
case x =>
}
}
class Foo extends DynamicComponent {
protected val component = new Component
}
new Foo // -> NullPointerException
The following things are not options for me:
Using protected lazy val component; that would produce an avalange of dozens of vals needing to become lazy, something I do not want.
Putting addListener in a method, e.g. initDynamic(); because I will be mixing in many traits, and I don't want to remember to call half a dozen initFoo() methods.
Using DelayedInit. This doesn't work with traits, at least according to the scaladocs.
I could live with a single init() call, but only under the following conditions:
all mixed in traits can easily declare to be invoked in this one single call
it is a compile error to forget the init() statement.
You can delay the initialization of a trait by by using early definitions. (See section 5.1.6 of the scala language specification)
class Foo extends {
protected val component = new Component
} with DynamicComponent
It's even clunkier than your solution, but you can always require the creation of a val that must be set with the init() method. You could choose to not do it last and get an error at runtime, but at least you won't forget it entirely:
class Component {
def addListener(pf: PartialFunction[Any, Unit]) {
println("Added")
}
}
trait Dyn {
protected def component: Component
protected val initialized: Init
class Init private () {}
private object Init { def apply() = new Init() }
def init() = { component.addListener{ case x => }; Init() }
}
class Foo extends Dyn {
protected val component = new Component
protected val initialized = init()
}
No cheating!:
> class Bar extends Dyn { protected val component = new Component }
<console>:12: error: class Bar needs to be abstract, since value
initialized in trait Dyn of type Bar.this.Init is not defined
class Bar extends Dyn { protected val component = new Component }
The advantage this has is if you need multiple things to be in place before you initialize all of them cooperatively, or if your Component class is final so you can't mix in anything else.
AN idea could be to use the trick described here:
Cake pattern: how to get all objects of type UserService provided by components
All your components that should be initialized could be registered in some Seq[InitializableComponent]. And then you could initialize all registered components with a foreach.
No component will be forgotten in that Seq because they are registered automatically, but you can still forget to call the foreach anyway...
Here is one idea (I am happy to read about other suggestions):
class Component {
def addListener(pf: PartialFunction[Any, Unit]) {
println("Added")
}
}
trait DynamicComponentHost {
protected def component: Component with DynamicPeer
protected trait DynamicPeer {
_: Component =>
addListener {
case x =>
}
}
}
class Foo extends DynamicComponentHost {
protected val component = new Component with DynamicPeer
}
new Foo
So basically I am forcing the component to mix in a type that can only be provided by the mixed in trait. Reasonable? Looks a bit too complicated in my eyes.

scala: how to wrap execution of subclass constructor?

in scala, i have a base class and a number of child classes. without adding code to a child class or changing the instantiation of a child class, i would like the base class to be able to call some code both before and after the child constructor is executed. before is easy since the base class constructor is called before the child's, but i don't see a way to handle the after case. as a bit of example code:
class A {
// do some stuff before child constructor is called
// ...
// do some other stuff after child constructor is called
// this could be a method or inline in the constructor, doesn't matter.
}
class B extends A { // stuff happens in between }
class C extends A { // stuff happens in between }
etc
val b = new B // everything happens inside, no other method call needed
is this behavior possible? thanks.
If you use Scala 2.9, you can arrange something like this:
class A {
println("Hi")
}
class B extends A with DelayedInit {
private[this] var count = 0
println("Hey")
def delayedInit(x: => Unit) {
x
count += 1
if (count==2) { println("There") }
}
}
class C extends B { println("Ho") }
class D extends C { println("Ha") }
This takes advantage of the new DelayedInit trait which sends delayed constructors from the current and all child classes to a delayedInit method. Unfortunately, since there is not a termination signal, you're limited to skipping a single constructor. So for C, we get:
scala> new C
Hi
Hey
Ho
There
where the "There" block has magically appeared after the "Ho" block from C. Unfortunately if you extend C, the new initialization happens last:
scala> new D
Hi
Hey
Ho
There
Ha
(You don't really need A there...I just put it there to illustrate what happens with superclasses.)
An 'end of concrete class' callback is possible,
the code below outputs :
hello
world1
world2
world3
end of the worlds !
trait A extends DelayedInit {
def delayedInit(body: => Unit) = {
body
println("end of the worlds !")
}
}
trait B extends A { println("hello") }
trait C extends B { println("world1") }
trait D extends C { println("world2") }
object Zozo extends D {
println("world3")
}

Is is possible to capture the type parameter of a trait using Manifests in Scala 2.7.7?

I'm writing a ServletUnitTest trait in Scala to provide a convenience API for ServletUnit. I have something like the following in mind:
/**
* Utility trait for HttpUnit/ServletUnit tests
*
* #param [T] Type parameter for the class under test
*/
trait ServletUnitTest[T <: HttpServlet] {
/**
* Resource name of the servlet, used to construct the servlet URL.
*/
val servletName: String
/**
* Servlet class under test
*/
implicit val servletClass: Manifest[T]
/**
* ServletUnit {#link ServletRunner}
*/
sealed lazy val servletRunner: ServletRunner = {
val sr = new ServletRunner();
sr.registerServlet(servletName, servletClass.erasure.getName);
sr
}
/**
* A {#link com.meterware.servletunit.ServletUnitClient}
*/
sealed lazy val servletClient = servletRunner.newClient
/**
* The servlet URL, useful for constructing WebRequests
*/
sealed lazy val servletUrl = "http://localhost/" + servletName
def servlet(ic: InvocationContext) = ic.getServlet.asInstanceOf[T]
}
class MyServletTest extends ServletIUnitTest[MyServlet] {
val servletName = "download"
// ... test code ...
}
This code doesn't compile as written, but hopefully my intent is clear. Is there a way to do this (with or without Manifests)?
While researching this topic, I found about a solution in this scala-list post by Jorge Ortiz, which did the trick for me, and is simpler than Aaron's.
In essence, his solution is (paraphrasing):
trait A[T] {
implicit val t: Manifest[T]
}
class B[T: Manifest] extends A[T] {
override val t = manifest[T]
}
(I'm ignoring the OP request to be 2.7.7 compatible as I'm writing this in 2011...)
For now, Scala represents traits as interfaces so this technique will work. There are some problems with this approach to implementing traits, however, in that when methods are added to a trait, the implementing class will not necessarily recompile because the interface representation only has a forwarding method pointing to another class that actually implements the method concretely. In response to this there was talk earlier this year of using interface injection into the JVM at runtime to get around this problem. If the powers that be use this approach then the trait's type information will be lost before you can capture it.
The type information is accessible with the Java reflection API. It's not pretty but it works:
trait A[T]{
def typeParameter = {
val genericType = getClass.getGenericInterfaces()(0).asInstanceOf[ParameterizedType]
genericType.getActualTypeArguments()(0)
}
}
class B extends A[Int]
new B().typeParameter -> java.lang.Integer
Some invariant checks should be added I've only implemented the happy path.
I found a solution that works, but it's pretty awkward since it requires the test class to call a method (clazz) on the trait before any of the trait's lazy vals are evaluated.
/**
* Utility trait for HttpUnit/ServletUnit tests
*
* #param [T] Type parameter for the class under test
*/
trait ServletUnitTest[T <: HttpServlet] {
/**
* Resource name of the servlet, used to construct the servlet URL.
*/
val servletName: String
/**
* Servlet class under test
*/
val servletClass: Class[_] // = clazz
protected def clazz(implicit m: Manifest[T]) = m.erasure
/**
* ServletUnit {#link ServletRunner}
*/
sealed lazy val servletRunner: ServletRunner = {
val sr = new ServletRunner();
sr.registerServlet(servletName, servletClass.getName);
sr
}
/**
* A {#link com.meterware.servletunit.ServletUnitClient}
*/
sealed lazy val servletClient = servletRunner.newClient
/**
* The servlet URL, useful for constructing WebRequests
*/
sealed lazy val servletUrl = "http://localhost/" + servletName
def servlet(ic: InvocationContext) = ic.getServlet.asInstanceOf[T]
}
class MyServletTest extends ServletIUnitTest[MyServlet] {
val servletName = "download"
val servletClass = clazz
// ... test code ...
}