[nem-en] Semantics of 'expose' macro construct when an exception is
thrown.
Gerard Murphy
g.j.murphy at sageserpent.com
Wed Dec 7 00:22:29 CET 2005
Hello,
I was investigating why the following class doesn't pass a unit test, when I
noticed that exceptions thrown in an 'expose' block are not propagated out
of the block.
This seems surprising. I would indeed expect the class invariant to be
checked on the object specified in the 'expose' statement, regardless of
whether the block completes normally or throws an exception: but in the
latter case I would also expect the exception to be rethrown and propagated
after checking the invariant (assuming the invariant wasn't violated).
Here's the code.
namespace SageSerpent.Core.TestSupport
{
using System;
using System.Collections.ObjectModel;
using Nemerle.Assertions;
using Nemerle.Imperative;
public
class TestCaseSet: KeyedCollection[Object, Object]
invariant AllTestCaseReferencesAreNonNull()
{
protected override
GetKeyForItem(item: Object): Object
{
item
}
protected override
InsertItem(index: Int32,
value: Object): void
requires value != null
{
System.Console.WriteLine("In InsertItem before expose block.");
expose(this)
{
base.InsertItem(index, value);
throw System.Exception("Bogus!") // ***** AN EXCEPTION
IS THROWN HERE ****
}
System.Console.WriteLine("In InsertItem after expose block.");
}
protected override
SetItem(index: Int32,
value: Object): void
requires value != null
{
System.Console.WriteLine("In SetItem before expose block.");
expose(this)
{
base.SetItem(index, value)
}
System.Console.WriteLine("In SetItem after expose block.");
}
private
AllTestCaseReferencesAreNonNull(): bool
{
foreach (testCaseReference in this)
{
when (testCaseReference == null) return false
}
true
}
}
}
During execution of the unit test, the TestCaseSet.InsertItem() method is
called repeatedly. However, observing the console output indicates that the
statement following the 'expose' block is executed; presumably the exception
is being 'eaten' by the macro expansion of the 'expose' block.
As far as I can see, the invariant is not being violated during execution of
the unit test: so I would expect to see the bogus exception being propagated
(as opposed to either a Nemerle.Assertion exception being propagated or
execution continuing normally after the 'expose' block).
I presume this is a bug - but I would welcome comments if this was the
intent of the language designers.
I'm completely in the dark as to what Spec# would do in this situation, by
the way. I'll go and have a look. :-)
Many thanks,
Gerard
Gerard Murphy www.sageserpent.com
More information about the devel-en
mailing list