chuckpreslar/emission

Anonymous functions are incompatible with the event emitter

Opened this issue · 1 comments

tul commented

If you create multiple closures using the same anonymous function, they all have the same pointer address because of how Go works. If you add these anonymous functions to the event emitter, removal of one of the listeners results in the removal of all of them.

package main

import (
"fmt"
"github.com/chuckpreslar/emission"
)

type action func()

func getCallback(myNumber uint32) action {
	fn := func() {
		fmt.Printf("number is %d\n", myNumber)
	}
	return fn
}

func main() {
	five := getCallback(5)
	six := getCallback(6)

	five()
	six()

	fmt.Printf("five addr %p six addr %p\n", five, six)  // <-- same address printed

	emitter := emission.NewEmitter()
	emitter.On("test",five)
	emitter.On("test",six)
	emitter.RemoveListener("test",five) // <-- removes both five and six
	emitter.EmitSync("test") // <-- does nothing (no listeners)
}

In this example, local vars five and six hold unique closures, which if executed will print different messages; however they have the same address. As the emitter tracks listeners by address, if we add both of these to the emitter on the same event, then remove one, it will remove both.

tul commented

I've proposed a fix in pull request #16, but as it breaks the existing interface it probably isn't something you'll want to merge - see what you think. Thanks!