Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #31599

Re: Abuse of AssertionError?

From Eric Sosman <esosman@comcast-dot-net.invalid>
Newsgroups comp.lang.java.programmer
Subject Re: Abuse of AssertionError?
Date 2015-04-21 11:21 -0400
Organization A noiseless patient Spider
Message-ID <mh5psa$ee5$1@dont-email.me> (permalink)
References <mh5gl0$96t$1@dont-email.me> <mh5mbn$vju$1@dont-email.me>

Show all headers | View raw


On 4/21/2015 10:21 AM, Jerry Stuckle wrote:
> On 4/21/2015 8:44 AM, Eric Sosman wrote:
>>
>>      A recent thread on `assert' prompts me to ask for opinions
>> about something I've been doing that may not be entirely kosher.
>> Now and then I write a method that computes and returns a value,
>> but whose computation relies on a data structure built elsewhere.
>> If that data structure is messed up the computation may go off
>> the rails, and I'd like to detect that.
>>
>>      For example, here's a (paraphrase of a) method that finds the
>> marginal income tax bracket for a stated income level:
>>
>>      private static double marginalTaxRate(double income) {
>>          income = Math.max(income, 0);
>>          for (int i = BRACKETS.length; --i >= 0; ) {
>>              if (income >= BRACKETS[i].floor) {
>>                  return BRACKETS[i].rate;
>>              }
>>          }
>>          // What goes here?
>>      }
>>
>> If everything has been set up correctly, the BRACKETS are arranged
>> in increasing order by their income floors and the floor of the
>> zero'th BRACKET is zero, so the `if' will eventually be satisfied
>> and the method will return a value.  But if something's amiss the
>> loop will run to completion -- and then the compiler will complain
>> about falling off the end of a value-returning method.
>>
>>      My solution has been to write
>>
>>      throw new AssertionError("BUG!");
>>
>> where the comment stands, and I'd like others to comment on whether
>> this is an acceptable practice, or suggest a better approach.
>>
>>      Red herrings that are of little interest:
>>
>>      - Using `double' for monetary calculations.  I solemnly swear that
>>        in the context from which this example was adapted, `double' is
>>        an entirely suitable choice.  Sue me.
>>
>>      - Rewriting the loop to remove the `i >= 0' test would silence
>>        the compiler's complaint.  But then if the BRACKETS were messed
>>        up I'd eventually get ArrayIndexOutOfBoundsException instead --
>>        even less informative than AssertionError, IMHO.
>>
>>      Thoughts?  Ideas?
>>
>
> This is one way to do it, and I wouldn't say it's wrong.  But it doesn't
> catch the error (a bad array) where it occurs; the code here may be a
> long way from the code that created the array.

     Thanks, Jerry.  In the particular program from which the example
was adapted, there's also an attempt to catch errors at the point where
the BRACKETS array is built.  Specifically, I've got something like

	static final Bracket[] BRACKETS = ...;
	static {
	    assert bracketsAreSane();
	}
	private static boolean bracketsAreSane() {
	    // assorted sanity checks here
	}

     However, this approach isn't always available.  For example, in
another program that uses Swing drag'n'drop operations I've got

	private static DataFlavor levelFlavor() {
	    try {
	        return new DataFlavor(
	            DataFlavor.javaJVMLocalObjectMimeType
                     + "; class=" + Level.class.getName());
	    } catch (ClassNotFoundException ex) {
	        throw new AssertionError("BUG! " + ex);
	    }
	}

Now, I "know" the DataFlavor constructor in this case isn't going to
throw up unless I misspelled something (e.g., "; clas="), so it seems
silly to force the caller to handle an exception that will "never"
occur.  To relieve the caller of the silly responsibility I've got to
write a `catch' block -- and what goes inside?

> I would make a class Brackets.  In the constructor I would ensure the
> array is created properly, then add a member such as
>
> public double getRate(double income);
>
> Then just call it with
>
>    double rate = bracket.getRate(income);

     Okay, but that just moves the problem back into the Brackets class,
which will have a loop similar to the one I showed.  Given the sanity
checks built into Brackets' constructor it might be defensible to write
an "infinite" loop to keep the compiler happy, b-u-u-t-...  It still
makes me queasy.

     Thanks for the comments.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Abuse of AssertionError? Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-04-21 08:44 -0400
  Re: Abuse of AssertionError? Jerry Stuckle <jstucklex@attglobal.net> - 2015-04-21 10:21 -0400
    Re: Abuse of AssertionError? Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-04-21 11:21 -0400
      Re: Abuse of AssertionError? Jerry Stuckle <jstucklex@attglobal.net> - 2015-04-21 11:31 -0400
  Re: Abuse of AssertionError? j4n bur53 <janburse@fastmail.fm> - 2015-04-21 16:59 +0200
    Re: Abuse of AssertionError? Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-04-21 11:26 -0400
  Re: Abuse of AssertionError? Thomas Richter <thor@math.tu-berlin.de> - 2015-04-21 17:05 +0200

csiph-web