assert(obj) is a mystery

Davidson Corry davidsoncorry at comcast.net
Wed Nov 9 16:36:34 PST 2011


On 11/9/2011 9:35 AM, Jonathan M Davis wrote:
> On Wednesday, November 09, 2011 05:39 Alex Rønne Petersen wrote:
>> On 09-11-2011 11:33, Jonathan M Davis wrote:
>>> On Tuesday, November 08, 2011 21:51:46 Davidson Corry wrote:
>>>> OK. Not addressing Alex's objections at all, it's not clear to me why
>>>> anyone would *need* to test the invariant of an object.
>>>
>>> I wouldn't expect it to be something that you'd need to do very often.
>>> However, if you give access to the member variables in your class or
>>> struct - either directly or indirectly - allowing code outside the type
>>> to modify that type's state, then the invariant can be violated. Now,
>>> it's arguably bad design to allow such access when using an invariant
>>> (if not in general), but it _is_ a case where the invariant can be
>>> invalidated.
>>
>> I do think Good Practice (TM) dictates that you shouldn't expose
>> something as mutable if mutating it violates the object's invariant.
>> Instead, you should use a property with preconditions.
>>
>> In light of this, I can actually see why assert(obj) testing the
>> invariant can seem very, very odd. (And I mean, nobody's going to write
>> assert(this) or something like that...)
>
> You _might_ write assert(this) if you've just called some private functions
> and wanted to be sure that the invariant is still valid. Since the entire
> module has access to private functions and variables, and since private
> functions do _not_ trigger the invariant, it's quite possible for even a well-
> written class or struct to get a messed up the variant if the module as a
> whole has bugs. And even if private were restricted to the type, if you were
> being thorough, you might want to run the invariant within your type after
> running some private functions.
>
> Still, I wouldn't expect assert(obj) or assert(this) to be common. The only
> time that I've used it was in debugging when I was trying to figure out when
> the invariant was invalidated within the type when there was a bug. So, I
> definitely think that it's useful to be able to explicitly call the invariant,
> but I'd also expect it to be quite rare.

Thanks, Jonathan. I had forgotten that something outside of the object 
itself could have mucked about with its innards, disrupting its 
invariant. That is, after all, the reason why the invariant is tested at 
entry to any public method: if it were *not* possible for the invariant 
to have been compromised while the object was "in the wild", there would 
be no need for the test-at-entry.

I think my point still stands, however. Any time you actually use "obj" 
(by calling one of its public methods) its invariant will be tested, and 
at that point you will learn that "obj" has been compromised. 
Conversely, if you have an "obj" that is compromised but you never use 
it, why would you even *care* about its invariant?

As far as I can tell, "assert(obj)" MEANS "test the invariant without 
using the object". And I don't see the point of that.

Alex's original complaint, if I understand it correctly, is that a bare 
mention of "obj" anywhere else is evaluated as a Boolean "obj !is null". 
ONLY IN "assert(obj)" does it have the special meaning of "obj !is null 
&& obj.invariant_holds".

Even though such special semantics are weird and somewhat 
counter-intuitive, given that they apply only in this one circumstance, 
I would be glad to have them *if they bought me something*. But I still 
don't see what they buy me.

-- Davidson

p.s. they are also unnecessary in that, if you really want to test an 
object without using it, simply have its class define a public method 
with an empty {} body, then call that method on the object to be 
validated. Since the method is public, it will test the class invariant 
(twice!) -- a bit tedious to have to define that method, yes, but as you 
say, the need for such testing should be rare, and thus doesn't (??) 
justify special syntax rules.

IMHO, YMMV, see boxtop for details, not available in all states, insert 
your favorite disclaimer here...



More information about the Digitalmars-d-learn mailing list