• LCrawford (unregistered)

    It looks like the design pattern was taken from the Gang of VBA, where every function was expected to have its own error handler and probably did log to an actual file back in the day.

  • (nodebb)

    It can throw if the string is null, but I'm willing to bet the string comes from something like TextBox.Text, which means it can never be null. It's deductive reasoning, we know the coders are morons, therefore unless we know otherwise, we assume the most idiotic situation possible.

  • (author) in reply to Mr. TA

    According to the docs, it accepts nulls.

  • (nodebb) in reply to Mr. TA

    @Mr. TA --- According to the documentation it does NOT, nor has it ever in my experience... https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.information.isnumeric

  • (nodebb)

    Mr. TA: I've decompiled IsNumeric, and it checks for a null input near the top. So, it won't throw if null. (And, for strings, it basically just wraps double.TryParse anyway).

  • (nodebb) in reply to TheCPUWizard

    I can't argue since I never actually worked with VB.NET but I did look at that same documentation page before posting and couldn't find anything about accepting nulls and still can't...

  • (nodebb) in reply to chucker23n

    This means they're even more silly, I was willing to grant them the tiny bit of goodwill and what resulted? They blew it.

  • dpm (unregistered)

    I looked at that doc page and saw this:

         "IsNumeric returns True if Expression is a string that contains a valid hexadecimal or octal number. "
    

    TRWTF is that there is no way to avoid/disable that behavior.

  • (nodebb) in reply to TheCPUWizard

    According to the documentation it does NOT

    The docs on that page don't actually say one way or the other what happens on a NULL, and it's easy to justify saying that it will do something bad, since all the defined return conditions say what is returned if the input is this or that kind of thing, except that NULL is not a thing. (Er, that's its job, to be not a thing.)

    So the return when you pass it a NULL is not defined.

  • (nodebb)

    At least vb,net returns False if you exit a boolean function without returning a value. In other languages, it could be anything

  • Sole Purpose Of Visit (unregistered) in reply to thosrtanner

    Not strictly true. In many languages (eg Rust) you get the result of the last expression. Which in this case (I think) would be the result of IsNumeric.

    Happily, therefore, this entire mess could be cross-compiled to a superior language (and I work extensively with VB.Net), and nobody would notice the difference!

    (BTW there really should be a using block around that Session creation. Normally it wouldn't matter, but, and assuming exceptions, the calling site might be looping over a collection of a million nulls ... with unappealing results.)

  • (author) in reply to Steve_The_Cynic

    Except the parameter signature in the docs is object?, which tells us that the parameter is allowed to be null. It doesn't say what it returns on a null, explicitly, which is a failing in the documentation, but it's reasonable to assume that a null is not a number, and thus we could reasonably expect it to return false. But null is definitely a valid input.

  • (nodebb) in reply to Remy Porter

    Good catch, I didn't notice that either.

  • (nodebb) in reply to Sole Purpose Of Visit

    IsNumeric won't have returned a result as it has thrown an exception. I'm not sure what the last statement in the catch block that has a returnable value is, but I doubt it'd going to be a valid Boolean.

    In some languages, it may be defined to be the value of the last expression, which will then be mangled to a boolean In some languages (e.g. C and C++) it is undefined what the return value is. In either case, it's rather more likely to return a true-ish value than False.

    Addendum 2021-08-25 08:18: So I'm pretty sure they would notice a difference

  • (nodebb)

    I'm not sure what the last statement in the catch block that has a returnable value is

    VB Functions work by using the function name as a virtual variable. In the absence of a return statement, this variable's value is returned. It's initially False, because that's the initialization rules of Boolean. Since the exception path never mutated it, the function will return False.

  • Sole Purpose Of Visit (unregistered) in reply to thosrtanner

    Good correction. I confused myself on the VB.Net vs others thing: absent an exception, VB.Net will return False (I believe, basically because it doesn't populate the boolean in As Boolean, so you get the default boolean), whereas the languages to which I alluded would indeed return the result of the last expression.

    I was also wrong on Rust, of course, because Rust doesn't throw exceptions, it returns a Result, which is basically a maybe monad. It actually takes effort to ignore that at the calling site, although you can use:

    let _ = failing()
    

    or

    let donotcare = failing().ok()
    

    or possibly other hideous constructs.

    In any case, not one of my better days.

  • Brian (unregistered)

    Well, you know what they say - some people are veterans with 20 years of experience, others are "veterans" with 1 year of experience 20 times.

  • Drak (unregistered) in reply to Remy Porter

    Actually, it's not a problem with the docs, if you are familiar with them. In all the Microsoft VB.Net docs, if a function CAN throw an exception it will have an 'Exception' header and a block containing all the possible exceptions that can be thrown, and the reason for them. So in this case the doc explicitely states no exceptions will be thrown. But only to those who are familiar with Microsoft's doc format.

  • my name is missing (unregistered)

    We are 1/5 of the way through the 21st century, surely still using VB.Net should be a permanent WTF.

  • Richard Brantley (unregistered)

    "It doesn't say what it returns on a null, explicitly, which is a failing in the documentation...."

    The beautiful thing is that a unit test will answer that question.

  • Barry Margolin (github) in reply to thosrtanner

    Watch your punctuation. I initially misread that as

    which will then be mangled to a boolean in some languages (e.g. C and C++)
    and was going to post a nasty reply that C/C++ doesn't do this.

  • I'm not a robot (unregistered) in reply to Drak
    So in this case the doc explicitely states no exceptions will be thrown.
    No. If the lack of mention of exceptions is supposed to imply that there will be no exceptions, then that's implicit, not explicit.

    Also, saying/implying that a null input won't result in a exception still isn't a complete specification. It should say what will happen in that case.

  • Sole Purpose Of Visit (unregistered) in reply to Richard Brantley

    The even more beautiful thing is that you can spend hundreds of hours writing unit tests that ensure the documentation is correct in each and every instance.

    For something like .NET, that would be, say, ten thousand documented APIs. Multiplied by, say, an average of ten tests per API call. Multiplied by the 30 mins or so you spend writing each test. Multiplied by the $100 per hour you charge as a Highly Paid Consultant Test Guru.

    And the even more beautiful thing is that you can write a simple screen scraper to capture and list all of those ten thousand documented APIs. So, if you miss one, you can blame it on the vendor, not on yourself.

    $5,000,000 for doing nothing useful at all, to anybody, at any time. Not to mention adding no value whatsoever to the tests that the vendor already does.

    Beautiful!

  • Barf4Eva (unregistered)

    sooooo........ remove exception handling, problem solved?

  • Naomi (unregistered) in reply to Barf4Eva

    You joke (probably?), but there are languages that take that approach. @Sole Purpose of Visit mentioned Rust as a well-known example.

  • 516052 (unregistered) in reply to Sole Purpose Of Visit

    The pro move is to only write those unit tests once (preferably with the help of a cople guys from india) for the entire API and than play solitare for all that budgeted time before copy pasting the results and taking the money.

  • (nodebb) in reply to Barf4Eva

    sooooo........ remove exception handling, problem solved?

    The function's name is "IsANumber". This is a general purpose function that would be useful in both UI and non-UI scenarios. The specific exception handler that was written in this case takes a formerly general purpose function and pins it down so it's only appropriate use is in a small number of user interface scenarios. So, yes, kill it with fire.

    The funny outcome of this analysis is that the function that they attempted to write (assuming you can infer intention from name), is already part of the library - and the only useful line of code in their function simply calls that library function.

    They would have been much better off to write:

        Private Function SomeTextBox_TextChanged(ByVal sender As Object,  ByVal e As EventArgs) As Boolean
            If Not IsNumeric(DirectCast(sender, TextBox).Text) Then
                err.Text = "There was an error." & ControlChars.CrLf & "Please try again later."
                err.CssClass = "cssLblError"
                Dim log As New logFile(Session("ConnectionString"), ex, "")
            End If
        End Function
    

    Of, course, all of the criticisms about "Please try again later" still apply.

  • markm (unregistered)

    As someone who has been using Microsoft products for over 30 years, some of the commenters above seem to be much too trusting of MS software and documentation. The documentation says IsNumeric accepts a null argument, but does not say what it returns in this case. I would not assume that it returns false; I can entirely see an MS supervisor deciding that, contrary to what all ordinary humans would think, it should return true. Maybe you'd better test that.

    Or I could see this supervisor failing to decide and approving code that returned true or false at random for a null, e.g., whatever happened to be left in a hardware register by the previous instructions. How could you test for that? One commenter mentioned compiling the source code for the function; maybe you need to read that source code. Or test for null before calling.

    Also, when the documentation doesn't mention exceptions, that's supposed to mean that the function does not throw any. But maybe it means that the programming team forgot to document the exceptions. That would be far from the worst error ever found in MS documentation. It's much faster to cut-and-paste a generic exception handler than to make sure it's not needed. (But if you don't know what exceptions may occur, how do you write the error message?)

    So, unless I was very familiar with this library function, I would make sure null is never passed to it. Perhaps that is assured when you get the string from a type-in-a-string dialog box, but I'd test for null if in doubt. It's always faster to prevent a bug than to find one.

    ...And that's one reason you need GBytes of RAM...

  • Craig (unregistered)

    The classical VB thing to do on a Null argument would be to return Null. But IsNumeric doesn't return a nullable Boolean, so that's out.

    Note that Err is a VBA compatibility thing that provided access to a sort of pseudo-exception with a code and a message. This code organization looks like it's a (bad) translation from an old VB code (maybe classic ASP that I think was VBScript?) that was doing some manipulation of the error message if IsNumeric failed.

Leave a comment on “Exceptional Numbers”

Log In or post as a guest

Replying to comment #:

« Return to Article