Em 14/10/2009 20:59, Martin McClure <martin@hand2mouse.com> escreveu:
csrabak@bol.com.br wrote: > Em 14/10/2009 17:11, Alexandre Bergel escreveu: > >>> In Squeak 3.10 TestCase >> assert: aBooleanOrBlock Squeak >>> 3.8, Dolphin and VAST (I don't know others) have: TestCase >>>>> assert: aBoolean So...is there a reason of doing that? Is >>> this expected? >> I do not see any particular reason. But having >> Object>>assert: aBlock is important, since one can simply >> redefine assert: in a class to supress all assertions. > Which begs the question: then why the same method is > re-implemented in TestCase anyway?
...just thinking 'aloud'...
TestCase>>assert:, by convention, accepts a Boolean, and could be extended to also accept a block (and apparently has been so extended in Squeak).
I see. I _think_ the idea of having it more 'compatible' with other dialects changing it back to accept a Boolean and keeping TestCase>>should: aBlock is a better way.
Object>>assert: *should* accept a block, and it isn't really useful for it to accept a Boolean.
I was keeping with your and Alexandre's reasoning, but when I look for HierarchyImplementors of #assert: starting from Object the only one I get (in a Pharo1.0beta dev image updated to 10470) are: Object>>assert: {error handling} TestCase>>assert: {accessing} So in Pharo we brought a functionality very up in the hierarchy.
As Alexandre says, you can suppress assertions by redefining #assert:. One could also make Object>>assert: depend on some variable somewhere to determine whether to actually run the assertion blocks. Then you can turn assertions on and off system-wide, and not be running that assertion code in the blocks all the time. If you accepted a boolean, you'd be running the assertion expression whether assertions were turned on or not, which is undesirable.
It's not too nice if Object>>assert: and TestCase>>assert: take different kinds of arguments
TestCase>>assert: takes a Boolean. I suspect that's too widely used to change.
I agrre as I wrote above, for blocks we have TestCase>>should:.
I don't know how widely used Object>>assert: is. Perhaps we could have a different selector for that which takes a block.
I don't either, but I find strange the complete hierarchy of classes of Pharo having a method assert: available. Perhaps I'm blindfolded and Pharo and Squeak have found a wider use for assertions?
Maybe a selector that implies more strongly that its argument should be a block.
I think TestCase>>should: suffices for that.
Our test framework (which I believe predates SUnit) uses #run:forResult:, with a block for the first argument and the expected result of evaluating the block as the second argument. I like this for a couple of reasons -- run: strongly implies that it should take a block argument, and giving the expected result separately allows failure messages of the form "Expected ; got " which is handy anytime but *really* useful when failures are not easily reproducible.
Yes, I see, but I think this is lateral to this discussion!
Regards,
-Martin
P.S. -- the following is marginally related:
In performance-critical code that is executed *very* frequently, even making a message send and checking whether assertions are turned on or not can have too much impact. In those situations, I banish all assertions to a subclass, which has methods of this general form:
someMethod | result | self assert: [assertions appropriate on entry to this method]. result := super someMethod. self assert: [assertions appropriate on exit from this method]. ^result.
Then to turn assertions on or off, I have code that can change the class of the instances, and switch whether new instances are of the no-assertions class or the with-assertions subclass.
This allows the application to run at full speed when assertions are turned off, a real advantage in some cases. This also separates the normal code from the assertion code, which has both advantages and disadvantages.
I really don't follow this, are you using assertions for checking invariants a la Eiffel?