Showing posts with label assert. Show all posts
Showing posts with label assert. Show all posts

Tuesday, March 16, 2010

Assert, Require, Assume

Very simple but useful are the methods assert, require and assume which are built into the Predef object. As you might expect they are methods for performing certain checks during runtime to verify certain conditions. They do not use the Java assert framework and therefore are always evaluated regardless of whether or not assertions are enabled.

Update: Scala 2.8 has an annotation called elidable that will (when 2.8 is complete) allow one to remove method calls at compile time by setting a compiler flag. The assert, etc... methods are all marked with this flag and as a result can be removed at compile time for production environments.

Scala2.8
  1. scala> var called = 0
  2. called: Int = 0
  3. scala> called
  4. res0: Int = 0
  5. /*
  6. assert, require and assume have call by name parameters so the message is only 
  7. calculated when the assertion fails.
  8. */
  9. scala> assert (called == 0, {called += 1; println("called is not 0")})
  10. scala> require (called == 0, {called += 1; println("called is not 0")})
  11. scala> assume (called == 0, {called += 1; println("called is not 0")}) 
  12. scala> called = 1
  13. called: Int = 1
  14. // demonstrating that the method is in fact called when the assertion fails
  15. scala> assert (called == 0, {called += 1; println("called is not 0")}) 
  16. called is not 0
  17. java.lang.AssertionError: assertion failed: ()
  18. at scala.Predef$.assert(Predef.scala:95)
  19. ...
  20. scala> called
  21. res4: Int = 2
  22. /*
  23. Require is intended to be used as a precondition of a method so 
  24. it throws an IllegalArgumentException, not an AssertionError
  25. */
  26. scala> require (called == 0, {called += 1; println("called is not 0")})
  27. called is not 0
  28. java.lang.IllegalArgumentException: requirement failed: ()
  29. at scala.Predef$.require(Predef.scala:117)
  30. ...
  31. scala> called                                                          
  32. res6: Int = 3
  33. scala> assume (called == 0, {called += 1; println("called is not 0")}) 
  34. called is not 0
  35. java.lang.AssertionError: assumption failed: ()
  36. at scala.Predef$.assume(Predef.scala:107)
  37. ...
  38. scala> called                                                         
  39. res8: Int = 4


scala 2.7.7
  1. /*
  2. In Scala 2.7 the parameter is evaluated before the 
  3. method is called so the side effect of the message causes
  4. the assertion to fail
  5. */
  6. scala> assert (called == 0, {called += 1; println("called is not 0")})
  7. called is not 0
  8. scala> called
  9. res2: Int = 1