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
scala 2.7.7
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
- scala> var called = 0
- called: Int = 0
- scala> called
- res0: Int = 0
- /*
- assert, require and assume have call by name parameters so the message is only
- calculated when the assertion fails.
- */
- scala> assert (called == 0, {called += 1; println("called is not 0")})
- scala> require (called == 0, {called += 1; println("called is not 0")})
- scala> assume (called == 0, {called += 1; println("called is not 0")})
- scala> called = 1
- called: Int = 1
- // demonstrating that the method is in fact called when the assertion fails
- scala> assert (called == 0, {called += 1; println("called is not 0")})
- called is not 0
- java.lang.AssertionError: assertion failed: ()
- at scala.Predef$.assert(Predef.scala:95)
- ...
- scala> called
- res4: Int = 2
- /*
- Require is intended to be used as a precondition of a method so
- it throws an IllegalArgumentException, not an AssertionError
- */
- scala> require (called == 0, {called += 1; println("called is not 0")})
- called is not 0
- java.lang.IllegalArgumentException: requirement failed: ()
- at scala.Predef$.require(Predef.scala:117)
- ...
- scala> called
- res6: Int = 3
- scala> assume (called == 0, {called += 1; println("called is not 0")})
- called is not 0
- java.lang.AssertionError: assumption failed: ()
- at scala.Predef$.assume(Predef.scala:107)
- ...
- scala> called
- res8: Int = 4
scala 2.7.7
- /*
- In Scala 2.7 the parameter is evaluated before the
- method is called so the side effect of the message causes
- the assertion to fail
- */
- scala> assert (called == 0, {called += 1; println("called is not 0")})
- called is not 0
- scala> called
- res2: Int = 1
Subscribe to:
Post Comments (Atom)
7 comments:
This of course leaves us wondering what the difference between assert and assume is.
Reply DeleteThere is no real difference. It just reads different.
Reply DeleteI didn't realise assert() was always enabled. It's pretty important to be able to disable asserts: is there a way?
Reply DeleteIn fact there is a way. I will address it in my next post. It is elidable compiler level Certain methods can be annotated so they will not be compiled given a certain compiler flag
Reply DeleteHmm seems the elidable compiler flags are not yet available in the snapshot. So I will wait on that post. But the idea is to be able to pass a flag to the compiler and certain method calls will be removed by the compiler to not have the overhead
Reply DeleteJesse - elidable has been in there for months and I just confirmed it's working fine. Don't know what issue you're having, but see the test case I just checked in if you need example usage.
Reply DeleteShouldn't that be "It's pretty important to not disable asserts". In Java I never use the assert statement because it is (by default) disabled in the field. Instead I use my own methods that can't be disabled. Often it is as important or more so to detect errors that occur in production as it is to detect errors during testing. For one thing, if errors are found in production, it indicates that there is a problem with your testing practices -- something you would probably want to know about.
Reply Delete