I want to override the val t from getValue which returns a Future
trait demo{
val t :String
}
class Test1 extends demo{
override val t = "abc"
}
class Test2 extends demo{
override val t = ""
private def getValue ={
Future(Option("abc"))
}
}
What you can do that kind of comes close to that is to map a future to an anonymous class extending demo:
val aDemo: Future[demo] = Future("abc").map { value =>
new demo {
override val t = value
}
}
Of course, you can do that inside a for-comprehension as well, e.g.:
for (value <- Future("abc")) yield
new demo {
override val t = value
}
Related
class Person {
val studentName = "Arpana"
def changeName(id:String, name:String) ={
val studentName = name
useName(id)
}
def useName(id:String) = {
println(s"use name is $id, by $studentName")
}
}
object Person {
def main(args: Array[String]): Unit = {
(new Person).changeName("2", "Shubham")
}
}
I don't want to use var in code, can we do it by keywords, I tried with keywords like super, protected, private, final but didn't work.
In actual I want to apply this in the below code.
abstract class BaseRepository[T <: BaseModel : ClassTag : StriveSerializer] {
self: BaseConnection =>
val tableName: String = implicitly[ClassTag[T]].runtimeClass.getSimpleName
private val serializer = implicitly[StriveSerializer[T]]
private def executeInserts(query: String): Future[Boolean] = Future {
val preparedStatement = self.connection.prepareStatement(query)
preparedStatement.execute()
}
def exist(id: String, name: String): Future[Boolean] = {
val tableName = name
val promise = Promise[Boolean]
queryById(id).onComplete {
case Success(_) => promise.success(true)
case Failure(ex) => promise.failure(ex)
}
promise.future
}
def queryById(id: String): Future[T] = {
val getSql = s"SELECT * FROM $tableName WHERE id == $id;"
executeReads(getSql).map(serializer.fromResultSet)
}
}
I want when i call exist function then table name given in exist function override in queryById method table name .
It seems like a bit of mix of Java and Scala style. I tried to refactor a bit assuming the intention behind the code. Try and see if this achieves what you want to do:
class Person(_id: String, _studentName: String) {
private val id: String = _id
private val studentName: String = _studentName
def useName() = {
println(s"use name is $id, by $studentName")
}
}
object Person extends App {
new Person("2", "Shubham").useName()
}
I think you should use case class For Model
case class Student(id:String,name:String)
def changeId(student:Student, newId:String): Student ={
student.copy(id=newId)
}
val s1 = Student("1","A")
val newS1 = changeId(s1,"2")
I think it okay to use mutable in a class
e.g.
class MySuperService{
var lastHeartbeat: Option[Timestamp] = None
def setLastHeartbeat(ts:Timestamp): Unit ={
lastHeartbeat = Some(ts)
}
}
val mss1 = new MySuperService()
mss1.setLastHeartbeat(???)
Say I have this situation
class Pipe {
var vel = 3.4
var V = 300
var a = 10.2
var in = ???
var TotV = V+in
var out = TotV*a/vel
}
val pipe1 = new Pipe
val pipe2 = new Pipe
The in variable is were my problem is, what i'd like to do is get the out variable from pipe1 and feed that in as the in variable for pipe 2 effectively to join the two pipes but I cant figure out if this is even possible in the same class. So I can do it manually but need to know if its possible to do in the class.
pipe2.in = pipe1.out
my attempted fix was to add an ID field then try and use that to reference an instance with a higher id field but that doesnt seem doable. ie
class Pipe(id:Int) {
var vel = 3.4
var V = 300
var a = 10.2
var in = Pipe(id+1).out //this is the sticking point, I want to reference instances of this class and use their out value as in value for instances with a lower ID
var TotV = V+in
var out = TotV*a/vel
}
any help would be appreciated
You can do this by defining a companion object for the class and passing in the upstream pipe as an optional parameter to the factory method, then extracting its in value and passing it to the class constructor, as follows:
object Pipe {
def apply(upstreamPipe: Option[Pipe]): Pipe = {
val inValue = upstreamPipe match {
case Some(pipe) => pipe.out
case None => 0 // or whatever your default value is
new Pipe(inValue)
}
You would then call
val pipe1 = Pipe(None)
val pipe2 = Pipe(Some(pipe1))
Unfortunately your question is not clear now. Under certain assumptions what you describe looks like what is now called "FRP" aka "Functional Reactive Programming". If you want to do it in a serious way, you probably should take a look at some mature library such as RxScala or Monix that handle many important in the real world details such as error handling or scheduling/threading and many others.
For a simple task you might roll out a simple custom implementation like this:
trait Observable {
def subscribe(subscriber: Subscriber): RxConnection
}
trait RxConnection {
def disconnect(): Unit
}
trait Subscriber {
def onChanged(): Unit
}
trait RxOut[T] extends Observable {
def currentValue: Option[T]
}
class MulticastObservable extends Observable with Subscriber {
private val subscribers: mutable.Set[Subscriber] = mutable.HashSet()
override def onChanged(): Unit = subscribers.foreach(s => s.onChanged())
override def subscribe(subscriber: Subscriber): RxConnection = {
subscribers.add(subscriber)
new RxConnection {
override def disconnect(): Unit = subscribers.remove(subscriber)
}
}
}
abstract class BaseRxOut[T](private var _lastValue: Option[T]) extends RxOut[T] {
private val multicast = new MulticastObservable()
protected def lastValue: Option[T] = _lastValue
protected def lastValue_=(value: Option[T]): Unit = {
_lastValue = value
multicast.onChanged()
}
override def currentValue: Option[T] = lastValue
override def subscribe(subscriber: Subscriber): RxConnection = multicast.subscribe(subscriber)
}
class RxValue[T](initValue: T) extends BaseRxOut[T](Some(initValue)) {
def value: T = this.lastValue.get
def value_=(value: T): Unit = {
this.lastValue = Some(value)
}
}
trait InputConnector[T] {
def connectInput(input: RxOut[T]): RxConnection
}
class InputConnectorImpl[T] extends BaseRxOut[T](None) with InputConnector[T] {
val inputHolder = new RxValue[Option[(RxOut[T], RxConnection)]](None)
private def updateValue(): Unit = {
lastValue = for {inputWithDisconnect <- inputHolder.value
value <- inputWithDisconnect._1.currentValue}
yield value
}
override def connectInput(input: RxOut[T]): RxConnection = {
val current = inputHolder.value
if (current.exists(iwd => iwd._1 == input))
current.get._2
else {
current.foreach(iwd => iwd._2.disconnect())
inputHolder.value = Some(input, input.subscribe(() => this.updateValue()))
updateValue()
new RxConnection {
override def disconnect(): Unit = {
if (inputHolder.value.exists(iwd => iwd._1 == input)) {
inputHolder.value.foreach(iwd => iwd._2.disconnect())
inputHolder.value = None
updateValue()
}
}
}
}
}
}
abstract class BaseRxCalculation[Out] extends BaseRxOut[Out](None) {
protected def registerConnectors(connectors: InputConnectorImpl[_]*): Unit = {
connectors.foreach(c => c.subscribe(() => this.recalculate()))
}
private def recalculate(): Unit = {
var newValue = calculateOutput()
if (newValue != lastValue) {
lastValue = newValue
}
}
protected def calculateOutput(): Option[Out]
}
case class RxCalculation1[In1, Out](func: Function1[In1, Out]) extends BaseRxCalculation[Out] {
private val conn1Impl = new InputConnectorImpl[In1]
def conn1: InputConnector[In1] = conn1Impl // show to the outer world only InputConnector
registerConnectors(conn1Impl)
override protected def calculateOutput(): Option[Out] = {
for {v1 <- conn1Impl.currentValue}
yield func(v1)
}
}
case class RxCalculation2[In1, In2, Out](func: Function2[In1, In2, Out]) extends BaseRxCalculation[Out] {
private val conn1Impl = new InputConnectorImpl[In1]
def conn1: InputConnector[In1] = conn1Impl // show to the outer world only InputConnector
private val conn2Impl = new InputConnectorImpl[In2]
def conn2: InputConnector[In2] = conn2Impl // show to the outer world only InputConnector
registerConnectors(conn1Impl, conn2Impl)
override protected def calculateOutput(): Option[Out] = {
for {v1 <- conn1Impl.currentValue
v2 <- conn2Impl.currentValue}
yield func(v1, v2)
}
}
// add more RxCalculationN if needed
And you can use it like this:
def test(): Unit = {
val pipe2 = new RxCalculation1((in: Double) => {
println(s"in = $in")
val vel = 3.4
val V = 300
val a = 10.2
val TotV = V + in
TotV * a / vel
})
val in1 = new RxValue(2.0)
println(pipe2.currentValue)
val conn1 = pipe2.conn1.connectInput(in1)
println(pipe2.currentValue)
in1.value = 3.0
println(pipe2.currentValue)
conn1.disconnect()
println(pipe2.currentValue)
}
which prints
None
in = 2.0
Some(905.9999999999999)
in = 3.0
Some(909.0)
None
Here your "pipe" is RxCalculation1 (or other RxCalculationN) which wraps a function and you can "connect" and "disconnect" other "pipes" or just "values" to various inputs and start a chain of updates.
I saw lots of websites about scala reflection library but none of them have a straightforward answer to instantiate an object of the class at runtime.
For example, I have the following code:
trait HydraTargetTable {
val inputTables = Seq.empty[Int]
val tableType: String
val tableName: String
val schema: StructType
def className: String = this.getClass.toString
}
trait HydraIntermediateTable extends HydraTargetTable {
val tableType = "Intermediate"
def build(textRDD: RDD[String]): DataFrame = {
DataframeUtils.safeParseFromSchema(textRDD, schema)
}
}
class Table1 extends HydraIntermediateTable {
override val inputTables: Seq[Int] = Seq(1, 2)
override val tableName: String = ""
override val schema: StructType = new StructType()
}
At runtime, I want to be able to instantiate an object of Table1 given the class name as a String value. Here is my reflection code.
object ReflectionTestApp {
def tableBuilder(name: String): Intermediate = {
Class.forName("hearsay.hydra.dataflow.api." + name).newInstance()
.asInstanceOf[Intermediate]
}
def hydraTableBuilder(name: String): HydraTargetTable = {
val action = Class
.forName("hearsay.hydra.dataflow.api." + name).newInstance()
action.asInstanceOf[HydraTargetTable]
}
def main(args: Array[String]): Unit = {
hydraTableBuilder("Table1").inputTables.foreach(println)
}
}
Here is how you can achieve reflection for Object/Class.
package reflection
trait Table {
val id: Int
}
class ActivityTable extends Table {
val id = 10
}
object ActivityTable2 extends Table {
val id = 10
}
object Reflection extends App {
val obj = activityTableBuilder("ActivityTable")
println(obj.id) //output 10
val obj2 = objectBuilder("ActivityTable2$")
println(obj2.id) //output 10
/*
class reflection
*/
def activityTableBuilder(name: String): Table = {
val action = Class.forName("reflection." + name).newInstance()
action.asInstanceOf[Table]
}
/*
object reflection
*/
def objectBuilder(name: String): Table = {
val action = Class.forName("reflection." + name)
action.getField("MODULE$").get(classOf[Table]).asInstanceOf[Table]
}
}
How do I invoke XYZ.doSomething method for these classes:
XYZ.scala
object XYZ {
private def doSomething(i : Int)(implicit s: String): String {
s + i.toString
}
}
XYZTest.scala
class XYZTest extends FunSpec with PrivateMethodTester {
describe("SomeTest") {
it("Can't find a private method named: doSomething :( ") {
implicit lazy val someStr: String = "sahil"
val doSomething = PrivateMethod[String]('doSomething)
val myStr = XYZ invokePrivate doSomething(1)
assert(myStr == "sahil1")
}
}
describe("SomeTest") {
it("This doesn't even compile :( ") {
val doSomething = PrivateMethod[String]('doSomething)
val myStr = XYZ invokePrivate doSomething(1)("sahil")
assert(myStr == "sahil1")
}
}
}
Correct answer is:
object XYZ {
private def doSomething(i : Int)(implicit s: String): String = {
s + i.toString
}
}
class XYZTest extends FunSpec with PrivateMethodTester {
describe("SomeTest") {
it("Can't find a private method named: doSomething :( ") {
implicit lazy val someStr: String = "sahil"
val doSomething = PrivateMethod[String]('doSomething)
val myStr = XYZ invokePrivate doSomething(1, someStr)
assert(myStr == "sahil1")
}
}
}
Brief view on invokePrivate method shows that it does not support implicits, but looks like it treats currying argument list as general sequence of arguments
def invokePrivate[T](invocation : PrivateMethodTester.this.Invocation[T])
where args is the sequence:
final class Invocation[T](val methodName : scala.Symbol, val args : scala.Any*)
I add variables with Dynamic from scala 2.10.0-RC1 like this:
import language.dynamics
import scala.collection.mutable.HashMap
object Main extends Dynamic {
private val map = new HashMap[String, Any]
def selectDynamic(name: String): Any = {return map(name)}
def updateDynamic(name:String)(value: Any) = {map(name) = value}
}
val fig = new Figure(...) // has a method number
Main.figname = fig
Now, if I want to access Main.figname.number it doesn't work, because the compiler thinks it's of type Any.
But it's also Main.figname.isInstanceOf[Figure] == true, so it's Any and Figure, but doesn't have Figures abilities. Now I can cast it like, Main.figname.asInstanceOf[Figure].number and it works! This is ugly! And I can't present this to my domain users (I'd like to build a internal DSL.)
Note: If I use instead of Any the supertype of Figure it doesn't work either.
Is this a bug in scala 2.10, or a feature?
It is quite logical. You are explicitly returning instances of Any. A workaround would be to have instances of Dynamic all along:
import language.dynamics
import scala.collection.mutable.HashMap
import scala.reflect.ClassTag
trait DynamicBase extends Dynamic {
def as[T:ClassTag]: T
def selectDynamic[T](name: String): DynamicBase
def updateDynamic(name:String)(value: Any)
}
class ReflectionDynamic( val self: Any ) extends DynamicBase with Proxy {
def as[T:ClassTag]: T = { implicitly[ClassTag[T]].runtimeClass.asInstanceOf[Class[T]].cast( self ) }
// TODO: cache method lookup for faster access + handle NoSuchMethodError
def selectDynamic[T](name: String): DynamicBase = {
val ref = self.asInstanceOf[AnyRef]
val clazz = ref.getClass
clazz.getMethod(name).invoke( ref ) match {
case dyn: DynamicBase => dyn
case res => new ReflectionDynamic( res )
}
}
def updateDynamic( name: String )( value: Any ) = {
val ref = self.asInstanceOf[AnyRef]
val clazz = ref.getClass
// FIXME: check parameter type, and handle overloads
clazz.getMethods.find(_.getName == name+"_=").foreach{ meth =>
meth.invoke( ref, value.asInstanceOf[AnyRef] )
}
}
}
object Main extends DynamicBase {
def as[T:ClassTag]: T = { implicitly[ClassTag[T]].runtimeClass.asInstanceOf[Class[T]].cast( this ) }
private val map = new HashMap[String, DynamicBase]
def selectDynamic[T](name: String): DynamicBase = { map(name) }
def updateDynamic(name:String)(value: Any) = {
val dyn = value match {
case dyn: DynamicBase => dyn
case _ => new ReflectionDynamic( value )
}
map(name) = dyn
}
}
Usage:
scala> class Figure {
| val bla: String = "BLA"
| }
defined class Figure
scala> val fig = new Figure() // has a method number
fig: Figure = Figure#6d1fa2
scala> Main.figname = fig
Main.figname: DynamicBase = Figure#6d1fa2
scala> Main.figname.bla
res40: DynamicBase = BLA
All instances are wrapped in a Dynamic instance.
We can recover the actual type using the as method which performs a dynamic cast.
scala> val myString: String = Main.figname.bla.as[String]
myString: String = BLA
You can add any extensions or custom functionalities to Any or any predefined value classes. You can define an implicit value class like this:
implicit class CustomAny(val self: Any) extends AnyVal {
def as[T] = self.asInstanceOf[T]
}
Usage:
scala> class Figure {
| val xyz = "xyz"
| }
defined class Figure
scala> val fig = new Figure()
fig: Figure = Figure#73dce0e6
scala> Main.figname = fig
Main.figname: Any = Figure#73dce0e6
scala> Main.figname.as[Figure].xyz
res8: String = xyz
The implicit value class is not costly like like regular class. It will be optimised in compile time and it will be equivalent to a method call on a static object, rather than a method call on a newly instantiated object.
You can find more info on implicit value class here.