Proper use of assertions

R

Razvan

Hi !





Take a look at the following code:

public class AssertTest
{
private y;

private void doSomething(int i)
{
assert (i < 100) : i = i % 100;
y = i;
}
}


The question was whether the above code makes proper use of
assertions. I answered 'yes', but the right answer was 'no' because of
the fact that the assertion has side effects. Indeed the variable 'i'
is modified inside the assert but why should this be inappropriate ? I
mean the program will end ANYWAY when the assertion is fired, so why
care if 'i' is modified or not before that ?

And what if this is what the developer really wanted to do: display
modulo of 'i' when i was bigger than 100 then end the application ?

Maybe the creator of the test assumes that the Error AssertionError
is caught somewhere ? (but to catch an AssertionError is a stupid
thing to do anyway)



Regards,
Razvan
 
C

Chris Smith

Razvan said:
private void doSomething(int i)
{
assert (i < 100) : i = i % 100;
y = i;
}
The question was whether the above code makes proper use of
assertions. I answered 'yes', but the right answer was 'no' because of
the fact that the assertion has side effects. Indeed the variable 'i'
is modified inside the assert but why should this be inappropriate ? I
mean the program will end ANYWAY when the assertion is fired, so why
care if 'i' is modified or not before that ?

And what if this is what the developer really wanted to do: display
modulo of 'i' when i was bigger than 100 then end the application ?

Maybe the creator of the test assumes that the Error AssertionError
is caught somewhere ? (but to catch an AssertionError is a stupid
thing to do anyway)

I agree with the right answer. You may have a great proof that when
everything is done as you expected, the assignment makes no difference.
Nevertheless, writing the above is at a minimum confusing and likely to
create fragile code that can break easily.

That said, the apparent intent of the question is to check whether you
realize that the latter expression will not be evaluated when assertions
are disabled. The code would only make sense if you were to assume that
the assignment happens when assertions are not checked (hence bringing
the argument into range). That doesn't happen, so the code is
nonsensical and confusing.

Incidentally, this narrowly skirts another reason why the use of
assertions is inappropriate. The assertion above checks a precondition,
and precondition checks should generally throw IllegalStateException or
IllegalArgumentException, not fail an assertion. Because the method is
private, though, the method is part of the implementation detail of the
class, and it's more acceptable to assert preconditions on the method.
Just don't extrapolate the same approach to a published API.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
P

Paul Lutus

Razvan said:
Hi !





Take a look at the following code:

public class AssertTest
{
private y;

private void doSomething(int i)
{
assert (i < 100) : i = i % 100;
y = i;
}
}


The question was whether the above code makes proper use of
assertions. I answered 'yes', but the right answer was 'no' because of
the fact that the assertion has side effects.

You mean, like terminating the program if the assertion fails, and changing
a variable's value as it does?
Indeed the variable 'i'
is modified inside the assert

The example isn't a very good one, because the variable is local, but the
principle is to avoid any side effects, otherwise the assertions become
themselves a source of errors.
but why should this be inappropriate ? I
mean the program will end ANYWAY when the assertion is fired, so why
care if 'i' is modified or not before that ?

There are much better examples. I think this one was meant to show the
principle, without a particularly bad result.
And what if this is what the developer really wanted to do: display
modulo of 'i' when i was bigger than 100 then end the application ?

The basic idea is to strictly avoid side effects in assertions so that the
program will run exactly the same whether or not assertions are enabled.
Otherwise the debugging usefulness of assertions is eroded (because the
assertions become a source of errors).

It is always possible to argue that a particular outcome is harmless, but
the tutorial purpose is met -- avoid side effects, even if there are no
obvious consequences.
 
A

Ann

Take a look at the following code:

public class AssertTest
{
private y;

private void doSomething(int i)
{
assert (i < 100) : i = i % 100;
y = i;
}
}


The question was whether the above code makes proper use of
assertions. I answered 'yes', but the right answer was 'no' because of
the fact that the assertion has side effects.

I read somewhere that assert should not be used to check
method parameters. Also, here you can just use an if statement.
 
R

Razvan

Ann said:
I read somewhere that assert should not be used to check
method parameters. Also, here you can just use an if statement.

Since the methos is private it is OK to use assertions. "if"
statements should be used when checking the parameters of public
methods. Of course there are situations when "if" statements are used
to check the parameters to private methods also. There is no rule
about this. In most cases experience will tell when to use assertions
and when "if"s.



Regards,
Razvan
 
Y

Yogo

Take a look at the following code:
public class AssertTest
{
private y;

private void doSomething(int i)
{
assert (i < 100) : i = i % 100;
y = i;
}
}


The question was whether the above code makes proper use of
assertions. I answered 'yes', but the right answer was 'no' because of
the fact that the assertion has side effects. Indeed the variable 'i'
is modified inside the assert but why should this be inappropriate ? I
mean the program will end ANYWAY when the assertion is fired, so why
care if 'i' is modified or not before that ?

Well, I have to disagree with the 'right' answer. The boolean-expression in
an assertion shouldn't have any side effect because the application may not
behave the same with assertions enabled or disabled. It doesn't matter if
the message-expression does have a side effect. Not that the assignment in
the example makes sense, so bad programming: yes. Inappropiate use of
assertions: no.
And what if this is what the developer really wanted to do: display
modulo of 'i' when i was bigger than 100 then end the application ?

No problem about that, a programmer is free to choose whatever message he
wants to be displayed and the following will do that (without the assignment
that makes no sense):

assert (i < 100) : i % 100;
Maybe the creator of the test assumes that the Error AssertionError
is caught somewhere ? (but to catch an AssertionError is a stupid
thing to do anyway)

Hmmm, I must agree that it's rather difficult to figure out what the creator
had in mind...

Regards,

Yogo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top