Search code examples
rx-scala

Why doesn't this execute the function given for RxScala's doOnSubscribe function?


  val x: Observable[Int] = Observable.just(1).doOnSubscribe(() => println(s"subscribed"))
  val y = x.subscribe(t => println(s"got item: $t"))
  println("all done")

I would have thought this code would print

subscribed
got item: 1
all done

But it doesn't print the initial "subscribed".


Solution

  • The signature of doOnSubscribe is:

    def doOnSubscribe(onSubscribe: => Unit): Observable[T] 
    

    That is, it takes a by-name argument. So you have to use it as follows:

    Observable.just(1).doOnSubscribe(println(s"subscribed"))
    

    by-name means that the println will not be executed when passed to doOnSubscribe, but only once doOnSubscribe uses it.

    What you were passing to doOnSubscribe is a 0-arity function, i.e. an expression of type () => Unit, and by discarding the value of an expression, Scala can turn any expression into Unit, so that's why it compiled.

    This is IMHO confusing, and I'd prefer a () => Unit argument instead of => Unit, then it would work as you expected.

    Btw: you are not the first to be puzzled by this ;-)