I'm so used to using matchers to pull out what I want that it never occurs to me that the int parser should be looser to compensate for sloppy patterns. For example, to get storage meat, I would do this:
Code:
int storage_meat = 0;
matcher m = create_matcher( "You have ([\\d,]+) meat in long-term storage", visit_url("storage.php") );
if ( m.find() )
storage_meat = m.group(1).to_int();
print( "You have " + storage_meat + " meat in storage" );
You find the pattern that (potentially) has the integer you want, and pull out exactly the integer. About the only way it could clearer, to my eye, is if we could do:
Code:
matcher m = create_matcher( "You have ([\\d,]+) meat in long-term storage", visit_url("storage.php") );
int storage_meat = m.find() ? m.group(1).to_int() : 0
I don't know "excise". I assume it finds stuff between other strings? If so, then the following is the equivalent:
Code:
int storage_meat = 0;
string str = excise(visit_url("storage.php"),"have "," meat").to_string();
if ( str != "any of your" )
storage_meat = str.to_int();
It would probably be clearer, in that case, if we provided "is_numeric( string)", which will return true or false, depending on whether the argument would pass muster for to_int() or not. As well as the ternary conditional operator I suggested for my own example.
I disagree with zarqon's characterization of code that narrows its attention to the actual numeric part of a string as "stupider" than sloppy code which shrugs and passes any-old-crap-string to the ASH runtime library and expects THAT to do the smart thing. That seems exactly the bass-ackwards way to characterize it.
I am also sure that I do not want to_int to pre-process a string and search out a single region of digits as a potential number, and reject the string if there are more than one such region.
I don't really want to be the one defending this, since it was Hola's decision, but, since we've all been dealing with the repercussions for 3 weeks or more now, I've come to agree that it was the philosophically correct decision. It also caused pain within KoLmafia core code, since that, too, was using sloppy patterns and depending on lots of extra code in the shim function that took strings and passed them on to Java's integer conversion - which is very strict, as you are now seeing, given all the NumericFormat exceptions.
I'll submit is_numeric( string ) to the ASH runtime library. See if it helps.
Edit: I just have to comment on this particular statement:
There's no reason for to_int() to treat an arbitrary string with no numeric characters as anything but 0.
Really? There is "no reason" for it to behave other than what you suggest? "No reason"?
Try telling that to the Java runtime library. Give a string with no numeric characters to Integer.parseInt(). The specification of that function says "The characters in the string must all be decimal digits, except that the first character may be an ASCII minus sign '-' ('\u002D') to indicate a negative value." Given that, there's obviously "no reason" that it should return anything but 0 if it is given a string containing nothing but non-numeric characters, is there?
Oh, wait. That's wrong. It throws a NumericFormatException if you try to do that.
ASH's to_int() is a wrapper for Java's Integer.parseInt(). We trim off white space. We remove commas. Therefore, we relax the input expectations - somewhat - for you. We used to do a whole bunch more cpu and memory allocation intensive string processing, before passing the string along. We no longer do this.
But, you say, there is "no reason" that to_int() shouldn't be doing such-and-such additional work for you? There is "no reason"?
That seems sort of arrogant of you.
Here's a function for you:
Code:
int sloppy_coder_version_of_to_int( string arg )
{
if ( is_numeric( arg ) )
return arg.to_int();
return 0;
}