Skip to content

Commit

Permalink
Fix #101: use applyOrElse instead of isDefinedAt
Browse files Browse the repository at this point in the history
  • Loading branch information
OlivierBlanvillain committed Apr 17, 2018
1 parent 606bb8b commit 0e55a54
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
22 changes: 16 additions & 6 deletions monadic-rx/shared/src/main/scala/mhtml/rx.scala
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,22 @@ object Rx {
case Collect(self, f, fallback) =>
var first = true
run(self) { a =>
val out =
if (f.isDefinedAt(a))
effect(f(a))
else if(first)
effect(fallback)
else ()
// Semantically:
// if (f.isDefinedAt(a))
// effect(f(a))
// else if(first)
// effect(fallback)
// else ()
//
// But we have to use applyOrElse to prevent double evaluation:
var isDefinedAt = true
val fa = {
f.applyOrElse(a, (_: Any) => {
isDefinedAt = false
fallback
})
}
val out = if (isDefinedAt | first) effect(fa) else ()
first = false
out
}
Expand Down
21 changes: 21 additions & 0 deletions monadic-rx/shared/src/test/scala/mhtml/RxTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -411,4 +411,25 @@ class RxTests extends FunSuite {
assert(sndList == List(-101, 1, 7))
assert(source.isCold && sndProxy.isCold)
}

test("no double checks with keepIf (#101)") {
val a = Var(0)
var checkCount = 0
val foo = a.keepIf { i =>
checkCount += 1
i > 0
}(0)

val cc = foo.impure.run(_ => ())

a := 1
a := 2
a := 3
a := 4

cc.cancel

assert(checkCount == 5)
assert(a.isCold)
}
}

0 comments on commit 0e55a54

Please sign in to comment.