noncom
noncom

Reputation: 4992

Scala - how to avoid closure?

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

Answers (1)

Didier Dupont
Didier Dupont

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

Related Questions