0
  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".

James Moore
  • 8,636
  • 5
  • 71
  • 90

1 Answers1

1

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 ;-)

Samuel Gruetter
  • 1,713
  • 12
  • 11
  • Ouch - you're right, I totally missed that. I added a comment to that bug - I think there's a way you can support both styles, at the cost of requiring an extra import. – James Moore Mar 29 '16 at 15:49