On 2010-11-21 14:06, Jonathan M Davis wrote:
On Sunday 21 November 2010 04:19:51 Jacob Carlborg wrote:
On 2010-11-21 02:34, Jonathan M Davis wrote:
On Saturday 20 November 2010 16:23:32 Jonathan M Davis wrote:
The lazy solution sounds pretty good actually. Can anyone think of any
real downsides to that? So, it would look something like

assertExcThrown(E : Throwable, T)(lazy T, string file = __FILE__, size_t
line = __LINE__);

Wait. No. I didn't think that one through enough. It doesn't work. You
You don't actually get a delegate out of lazy, and what you need for
assertExcThrown!() is a delegate. It would be great to be able to
implicitly create a delegate like that, but lazy does it underneath the
hood, so to speak, and when the function call is made, you still get the
result of the function call, and by that point, it's too late, since to
get the result of the function call, you obviously need to have called
it. So, the question remains whether it would be better to pass a string
which gets mixed in or a delegate which gets called.

Ok, now I'm not sure what you mean. If you don't get a delegate what do
you get? And what to you mean by "and by that point, it's too late", do
late for what?

I think that the delegate solution is uglier to use, but that's
debatable. It's less efficient at runtime, but it would be faster to
compile and would result in less code bloat (though how much code bloat
matters for unit tests is debatable, since they shouldn't end up in
released binaries). I'm really not sure which is better. I like the
mixin solution, but the delegate solution has its advantages as well.

Anyone else have an opinion on whether (and why) the string mixin
approach or the delegate approach is better?

- Jonathan M Davis

This works according to the documentation of assertExcThrown:

void foo (int, int)
{
      throw new Throwable("");
}

void assertExcThrown (E = Throwable, T) (lazy T dg, string file =
__FILE__, size_t line = __LINE__)
{
      bool thrown;

      try
          dg();

      catch (E e)
          thrown = true;

      if (!thrown)
          throw new AssertError(format("assertExcThrown() failed: No %s
was thrown.", E.stringof), file, line);
}

void main ()
{
      assertExcThrown(foo(3, 4));
}


Okay. I obviously don't use lazy enough and am probably posting too often
without enough sleep. I was thinking that with a lazy parameter, whatever
delegate which was created for it was called and the value assigned to the
function argument before the function body was actually entered. So, internally
to the function, it didn't matter at all whether a parameter was lazy or not, as
if the laziness of the parameters affected the outside of the function only and
not the inside. But that would completely defeat the point of lazy and makes no
sense at all.

Now, the code that you give works, and I think that it shows that using lazy is
exactly what assertExcThrown _should_ do. It allows for you to do a normal
function call and then have it explicitly called within the function block
without having to create a delegate or give the function call as a string. It
annoys me a bit to have the extra overhead of the delegate, and part of me does
think that it's silly to have a lazy parameter which is _always_ called, but it
does the job, and it creates less code bloat than the mixin solution, and if
speed is the main concern, the extra compilation overhead of the mixin solution
is probably greater than the overhead of the delegate, so if you expect to
compile and then immediately run the unit tests, the overall result of using a
delegate is likely faster. And the lazy parameter gets rid of any ugliness that
creating a delegate might have over the string mixin.

So, I'll change it to work with a lazy parameter instead. Thanks for your help.

- Jonathan M Davis

I don't know if the compiler can inline delegates or not but if it can I think this case would be very easy for the compiler to inline the delegate.

--
/Jacob Carlborg

Reply via email to