Reputation: 4992
How to avoid closure when passing a function as a parameter to a class constructor?
My class constructor accepts a function of type () => Unit
. During the program working process, I want to access a key-value pair from a mutable map, that was not defined at the moment of creating the object with the constructor
val cats = scala.collection.mutable.Map[String, Cat]
class Trigger(period: Long, f: () => Unit) {
//pseudocode:
when period passes, f()
}
someWonderfulObject += new Trigger (1000, () => cats("Hershy").meow)
cats += ("Hershy" -> Cat())
and then, when the wonderful object triggers its triggers, I get the error that there is no key like "Hershy". I conclude that apparently, this is due to the f
passed to the Trigger
cons being closured in a state when there was no "Hershy".
My question is now - how to avoid Scala making use of closures here and instead look at the actual state of cats
?
UPDATE:
The code for "when period passes" is this:
def update(tpf: Float) {
timePassed += tpf
if(timePassed > period) f()
}
The tpf
value comes from above, so here all this seems ok.
UPDATE:
I have found the problem to be in another, totally irrelevant place, I have confused the containers of all this stuff. Howevr, thank you all, I have learned something from the answers.
Upvotes: 0
Views: 389
Reputation: 29548
Closures do no such thing (that would be quite hard to specify, have terrible performance, and make the whole thing useless). The closure may contains a reference to cats, or to the instance containing cats, not a copy.
This code works as expected :
val cats = collection.mutable.Map[String, String]()
class Trigger(name: String, f: () => Unit) {
def fire = {
println("Fire " + name)
f()
}
}
val trigger = new Trigger("calling Hershy", () => println(cats("Hershy")))
cats += "Hershy" -> "meow"
trigger.fire // prints Fire calling Hershy
The closure is not at fault, I suspect this is something that does not appear in your sample.
Upvotes: 6