Often we need objects that can be reused and takes some time to generate:
def foo() = {
// long lines of code...
val pattern = Pattern.comile("pattern") // suppose this takes long time
// use pattern
}
Then it can be moved to outer scope
private[this] lazy val pattern = Pattern.comile("pattern") // suppose this takes long time
def foo() = {
// long lines of code...
// pattern need to be available only here!
// use pattern
}
But this complicates the source because it leaks scope of the variable pattern, while it is used only in specific location of foo. I am curious about this can be simplified with a macro function:
def foo() = {
// long lines of code...
val pattern = singleton { Pattern.comile("pattern") }
// use pattern
}
If it is possible, we can extend it for more interesting case; ThreadLocal singleton:
def foo() = {
// long lines of code...
val obj = threadLocal { new NotThreadSafeObject() }
// use obj
}
Which will be extended as:
private[this] lazy val foo_obj_gen_by_macro = {
val tl = new ThreadLocal[NotThreadSafeObject]()
tl.set(new NotThreadSafeObject())
tl
}
def foo() = {
// long lines of code...
val obj = foo_obj_gen_by_macro.get
// use obj
}
If it would C++, this can be very easily achieved by using static variable inside of function scope:
void foo() {
// long lines of code...
static Pattern pattern = Pattern.Compile("pattern");
// use pattern
}
Why not just scope it ?
lazy val foo: () => String = {
val pattern = Pattern.compile("pattern")
def result(): String = ???
result _
}
Or as thoredge mentioned even simpler
lazy val foo: () => String = {
val pattern = Pattern.compile("pattern")
() => ???
}
Related
I want to return the name of the corresponding uop according to the ordinal number of the uop.
I have tried various methods without success. I feel that there is a problem with the type usage of chisel and scala.
After I've relearned scala and chisel's use of variables, I'm still not quite sure what to do.
object GetUopcStr
{
def apply(uopc: UInt) = {
val uopStr = VecInit("uopNOP","uopLD","uopSTA","uopSTD")
uopStr(uopc)
}
}
object GetUopcStr
{
def apply(uopc: UInt) = {
val uopStr = Seq("uopNOP","uopLD","uopSTA","uopSTD")
val multiVec = VecInit(for(string <- uopStr) yield string)
// or
// val multiVec = VecInit(strings)
multiVec(uopc)
}
}
object GetUopcStr
{
def apply(uopc: UInt) = {
val uopStr = Seq("uopNOP","uopLD","uopSTA","uopSTD")
uopStr(uopc)
}
}
Both methods above have errors. I guess the above is a function in scala syntax. I'm supposed to generate the circuit inside. So in the end it should be chisel's Vec type.
I wanted to know if theres a way to override a method within the same class in scala.
class xyz {
def a() : Unit = {
var hello = "Hello"
}
def b() : Unit = {
//method to override the functionality of b, for example lets say I want it to just print "Hi, how is your day going" until its somehow reset and after its resett it should go back to doing var hello = "Hello"
}
}
def c() : Unit = {
//reset a to do what it was doing earlier (var hello = "Hello")
}
Basically I want to compute var hello = "Hello" whenever a() is called until b() is called and then a() should print "Hi, how is your day going" until its reset when c() is called and then it should go back to performing var hello = "Hello". Is there a way to use this, if not is there another way? I don't want to use conditionals. Thanks in advance.
So, basically you want to define a() to use a dynamic behaviour.
object Behave {
val helloComputeBehaviour: () => Unit =
() => {
// default behaviour
var hello = "Hello"
}
val printDayGreetingBehaviour: () => Unit =
() => {
// behaviour after switch
println("Hi, how is your day going")
}
var behaviour: () => Unit =
helloComputeBehaviour
def a(): Unit =
behaviour()
def b(): Unit = {
// switch behaviour
behaviour = printDayGreetingBehaviour
}
def c(): Unit = {
// go back to default behaviour
behaviour = helloComputeBehaviour
}
}
As someone who strongly prefers not to use vars, I do not think the following is elegant, but if vars are your cup of tea, you could do something like this:
class xyz {
private val resetHello: () => Unit = () => {
// set hello ...
}
private val printHi: () => Unit = () => {
// print "Hi..."
}
// variable holding the current behavior of def a()
private var behaviorOfA: () => Unit = resetHello
def a(): Unit = {
// execute the current behavior
behaviorOfA()
}
def b(): Unit = {
behaviorOfA = printHi
}
def c(): Unit = {
behaviorOfA = resetHello
}
}
In the Programming in Scala (Ch. 10 on "Composition & Inheritance") book there is an example which causes some misunderstandings. This is the extracted part:
abstract class Element {
def contents: Array[String]
val someProperty: String = {
println("=== Element")
contents(0)
}
}
class UniformElement(
str: String
) extends Element {
val s = str
println("=== UniformElement.s " + s)
def contents = Array(s) // error
//def contents = Array(str) // ok
}
val e = new UniformElement("str")
println(e.someProperty)
For some reason the initialization of superclass occures before s initialisation:
scala example.scala
=== Element
=== UniformElement.s str
null
Why does the alternative work without s (see commented line in code)?
The issue is field values are null until constructor completes, and super constructor is referencing indirectly value s which is initialised by child constructor, but the child constructor has not yet completed. The situation looks something like this
class UniformElement {
def <init>(str: String) = {
super.<init>()
s = str
}
}
where we can see if we replace super.<init>() with
val someProperty: String = {
println("=== Element")
contents(0)
}
that it executes before
s = str
Initialisation order issues can often be addressed by changing eager val s into lazy like so
class UniformElement(str: String) extends Element {
lazy val s = str
println("=== UniformElement.s " + s)
def contents = Array(s)
}
which now outputs
=== Element
=== UniformElement.s str
str
Thanks for the interesting question ! My guess (after spending some time on Scastie) would be this order of initialization :
Arguments : in your case, str is the first value to be defined
Parent : in your case, Element
Child : in your case, UniformElement
So, if I try to put it in a single class order, it goes like this :
class UniformElement{
// Argument init
val str = "str"
// Super constructor
def contents: Array[String]
val someProperty: String = {
println("=== Element")
contents(0)
}
// Child constructor
val s = str
println("=== UniformElement.s " + s)
def contents = Array(s) // error
//def contents = Array(str) // ok
}
The trick is that, to init someProperty, scala need to evaluate contents(0) and find contents definition. But when finding definition, s is not yet defined (and str is).
So final 'runtime' process:
class UniformElement{
// Argument init
val str = "str"
// Super constructor with contents replaced by definition
val someProperty: String = {
println("=== Element")
Array(s)(0) // error : s doesn't exists !
// Array(str)(0) // ok : str exists
}
// Child constructor
val s = str
println("=== UniformElement.s " + s)
def contents = Array(s) // error
//def contents = Array(str) // ok
}
To convince yourself, you can try :
println(e.someProperty) // null => s wasn't defined
println(e.contents(0)) // str => s is now defined
Feel free to ask for clarification if needed.
I am quite new to the scala programming language, and I currently need to do the following. I have a signleton object like the following:
object MyObject extends Serializable {
val map: HashMap[String, Int] = null
val x: int = -1;
val foo: String = ""
}
Now i want to avoid to have to serialize each field of this object separately, thus I was considering writing the whole object to a file, and then, in the next execution of the program, read the file and initialize the singleton object from there. Is there any way to do this?
Basically what I want is when the serialization file doesn't exist, those variables to be initialized to new structures, while when it exists, the fields to be initialized from the ones on the file. But I want to avoid having to serialize/deserialize every field manually...
UPDATE:
I had to use a custom deserializer as presented here: https://issues.scala-lang.org/browse/SI-2403, since i had issues with a custom class I use inside the HashMap as values.
UPDATE2:
Here is the code I use to serialize:
val store = new ObjectOutputStream(new FileOutputStream(new File("foo")))
store.writeObject(MyData)
store.close
And the code to deserialize (in a different file):
#transient private lazy val loadedData: MyTrait = {
if(new File("foo").exists()) {
val in = new ObjectInputStream(new FileInputStream("foo")) {
override def resolveClass(desc: java.io.ObjectStreamClass): Class[_] = {
try { Class.forName(desc.getName, false, getClass.getClassLoader) }
catch { case ex: ClassNotFoundException => super.resolveClass(desc) }
}
}
val obj = in.readObject().asInstanceOf[MyTrait]
in.close
obj
}
else null
}
Thanks,
No needs to serialize an object with only immutable fields (because the compiler will do it for you...) I will assume that the object provides default values. Here is a way to do this:
Start by writing an trait with all the required fields:
trait MyTrait {
def map: HashMap[String, Int]
def x: Int
def foo: String
}
Then write an object with the defaults:
object MyDefaults extends MyTrait {
val map = Map()
val x = -1
val foo =
}
Finally write an implementation unserializing data if it exists:
object MyData extends MyTrait {
private lazy val loadedData: Option[MyTrait] = {
if( /* filename exists */ ) Some( /*unserialize filename as MyTrait*/)
else None
}
lazy val map = loadedData.getOrElse( MyDefault ).map
lazy val x = loadedData.getOrElse( MyDefault ).x
lazy val foo = loadedData.getOrElse( MyDefault ).foo
}
coming from my other question is there a way to get by-name-parameters for constructors working? I need a way to provide a code-block which is executed on-demand/lazy/by-name inside an object and this code-block must be able to access the class-methods as if the code-block were part of the class.
Following Testcase fails:
package test
class ByNameCons(code: => Unit) {
def exec() = {
println("pre-code")
code
println("post-code")
}
def meth() = println("method")
def exec2(code2: => Unit) = {
println("pre-code")
code2
println("post-code")
}
}
object ByNameCons {
def main(args: Array[String]): Unit = {
val tst = new ByNameCons {
println("foo")
meth() // knows meth() as code is part of ByNameCons
}
tst.exec() // ByName fails (executed right as constructor)
println("--------")
tst.exec2 { // ByName works
println("foo")
//meth() // does not know meth() as code is NOT part of ByNameCons
}
}
}
Output:
foo
method
pre-code
post-code
--------
pre-code
foo
post-code
This is because when you're making an instance like this:
val tst = new ByNameCons {
...
}
.. you're actually creating an anonymous class, like in java.
The above code is the same as:
val tst = new ByNameCons() { ... }
.. while the correct syntax for passing by-name is:
val tst = new ByNameCons( { ... } )
You cant omit parentheses the same way for constructors as with functions.
val tst = new ByNameCons( {
println("foo")
} )
Thought it is probably just easier to do this:
object ByNameCons {
def apply(code: => Unit) = new ByNameCons(code)
}
val tst = ByNameCons { // no "new" here -- can't mix traits either
println("foo")
}
I dont know why, but it appears that using {} or () when creating the class changes the behavior. Using the following class,
class Coder(code: => Unit) {
def exec = {
println("before")
code
println("after")}
}
}
scala> val brackets = new Coder {println("testing")}
testing
brackets: Coder = $anon$1#1af7a03
scala> brackets exec
before
after
Now instead if defined another way,
scala> val parens = new Coder(println("testing"))
parens: Coder = Coder#dca3ed
scala> parens exec
before
testing
after
as desired. It seems as if in the first notation, the compiler is interpreting the brackets as a block to be evaluated to Unit, instead of an anonymous function which, when called, evaluates to Unit.
FWIW, using ({ ... }) also works fine.