Abort: perhaps not the end of the world?

dj_d

Member
I was surprised at the "scope" of the abort command. Given:

Code:
---die.ash---
void die()
{ abort();}
I would expect that this:
Code:
import<die.ash>;
die();
print("And now I'm back.  I had a snack.");
would never print anything. But I was surprised to find that this:
Code:
cli_execute("call die.ash");
print("And now I'm back.  I had a snack.");
didn't print anything either. Is that just me? It seems like the opposite behavior would be useful, so you can cli_execute call scripts that might want to use abort (notably: bounty.ash) without ending execution of your master script (like breakfast.ash).
 

heeheehee

Developer
Staff member
Right now, I guess the workaround is to have functions as booleans instead of voids. And instead of abort, return false; (true in the event that you have completed all conditions). I'm really not sure, as I haven't tested any of this.

I'd like to see this alternate form of abort, as well, as you can always use
Code:
cli_execute("abort");
to duplicate the current abort, right?
 
If you call a script from within another script and use exit instead of abort() it should exit the called script and continue executing the original script. So, instead of abort() try this:

Code:
---die.ash---
void die()
{ exit;}
void main()
{die();}
This will stop the script and nothing prints.
Code:
import<die.ash>;
die();
print("And now I'm back.  I had a snack.");
this will allow the master script to continue:
Code:
cli_execute("call die.ash");
print("And now I'm back.  I had a snack.");
There was a discussion on abort() being over used and this is probably an example of where the use of exit would be better.
 
Return ends the current function & exit ends the entire script.

In the following example "Goodbye" will never be printed, but "The end!" will.
Code:
void do_something(){
    print("Hello");
    return;
    print("Goodbye");
}

void main(){
    do_something();
    print("The end!");
}
As opposed to this where neither "Goodbye" nor "The end!" will get printed:
Code:
void do_something(){
     print("Hello");
     exit;
     print("Goodbye");
 }
 
 void main(){
     do_something();
     print("The end!");
 }
I don't know if that helps.
 

dj_d

Member
This is all true but somewhat irrelevant to my point, which is that - given a script that calls abort, which I *didn't* write, it would be nice to be able to contain that script's functionality, including it's decision to self-terminate, without it bringing down the parent script.
 

lostcalpolydude

Developer
Staff member
This is all true but somewhat irrelevant to my point, which is that - given a script that calls abort, which I *didn't* write, it would be nice to be able to contain that script's functionality, including it's decision to self-terminate, without it bringing down the parent script.

What if you wanted a script to halt the calling script? The functionality shouldn't be completely removed. Why not ask the person maintaining the script to change it to exit, or change it yourself if they aren't regularly updating?
 

Veracity

Developer
Staff member
Your example tries to distinguish between

...your script....
die();
...more of your script...

and

...your script....
call die.ash
...more of your script....

In other words, calling a function - which you may or may not have written - vs. calling another script - which you may or may not have written. In both cases, you want the external function to be able to call abort() and, somehow, KoLmafia is supposed to recognize that in the first case, that means "abort out of scripting" and in the second case it does not mean that.

The problem is that "abort" sets global KoLmafia state, not script specific state. It sets the same variable that internal functions set to signal that an unrecoverable error has occurred and that KoLmafia should print a message, make the screen red, stop automated tasks started via the GUI - and stop all scripts back to the CLI prompt. If that is the behavior you want, then "abort" is precisely the correct command to use in your script.

But in your example, that is NOT the behavior you want, and therefore, "abort" is NOT the correct command to use. You know the solution: use the "exit" statement to return from the currently executing script. That changes the state of the current script interpreter only, rather than KoLmafia's global execution state. If scripts use abort, with all that implies, when they really mean exit, they are buggy.

I disagree that changing the semantics of abort to match those of exit is the correct solution.
 

dj_d

Member
Makes sense. OK, I will fix this in my scripts and encourage others to do so in theirs. I guess, to summarize:

exit(): The script needs to stop.
abort(): All scripted execution needs to stop; something has gone horribly awry.

Right?
 

Grotfang

Developer
Makes sense. OK, I will fix this in my scripts and encourage others to do so in theirs. I guess, to summarize:

exit(): The script needs to stop.
abort(): All scripted execution needs to stop; something has gone horribly awry.

Right?

I brought this issue up (as That FN Ninja linked to) over a month ago. I use exit when exit is needed, and tend to add an abort parameter; if it's set to true I abort, anything else, I exit.

Code:
if( get_property( "script_abort" ) == "true" ) abort(); 
else exit;

This does me fine, and I very rarely set the property to true.
 

dj_d

Member
One problem - exit() can't be used with the same syntax as abort(string). Can we get an exit(string) so it can be a drop-in replacement?
 

zarqon

Well-known member
This discussion makes me realize that I should probably change vprint(message,0) to exit rather than abort. I have been encouraging all script authors that import ZLib to replace all abort(message) with vprint(message,0).

In which case, ZLib's vprint() would be a drop-in replacement.
 
Top