CLI to ASH, am I doing it right?

Veracity

Developer
Staff member
Here is an example of what I mean by "function returning prematurely":
PHP:
boolean test()
{
	print( "start test" );
	retrieve_item( 1, $item[ Xlyinia notebook ] );
	print( "end test" );
	return true;
}

void main()
{
	test().print();
}
will result in:
> call test.ash

start test
You need 1 more Xlyinia's notebook to continue.
false
This is behaving exactly as intended.

Keep in mind that ASH is the "Advanced Script Handler". Although it is C-like in syntax, it is a scripting language. Scripts are expected to abort execution if a command fails. So, the following CLI script:

Code:
acquire 3 Mae West
adventure 1 Fudge Mountain
drink 3 Mae West
can abort at any of those commands. The simple minded translation of that script to ASH:

Code:
retrieve_item( 3, $item[ Mae West ] );
adventure( 1, $location[ Fudge Mountain ] );
drink( 3, $item[ Mae West ] );
can, similarly, abort after any of the built-in functions.

It looks like a problem with ASH to me.
Nope.

The same happens with adventure() for example, and this is why scripters have to capture its return value.
Yup. It is behaving exactly as intended.

Checking if retrieve_item() returned false and aborting the script if needed should be the scripter's job. Having a function returning prematurely could upset the rest of the script without dealing with the problem, if the scripter doesn't capture the return value.
Yup.
 
Last edited:

fronobulax

Developer
Staff member
It seemed counter-intuitive

Matter of opinion :)

Just in case it isn't clear to visitors from the future

Code:
retrieve_item( 3, $item[ Mae West ] );

can and will abort by design if retrieve_item returns false.

Code:
boolean retVal;
retval = retrieve_item( 3, $item[ Mae West ] );

won't abort but a wise and careful scripter will check the return value and Do The Right Thing anyway.
 

slyz

Developer
Code:
retrieve_item( 3, $item[ Mae West ] );

can and will abort by design if retrieve_item returns false.
It won't abort the script, it will just return from the currently executing function (or effectively abort if it was on the top level).
 

Veracity

Developer
Staff member
It won't abort the script, it will just return from the currently executing function (or effectively abort if it was on the top level).
That surprises me.

PHP:
boolean a()
{
    print( "in a about to retrieve_item" );
    retrieve_item( 1, $item[ steaming evil ] );
    print( "in a after retrieve_item" );
    return true;
}

boolean b()
{
    boolean val = false;

    print( "calling a" );
    val = a();
    print( "a returned " + val );

    return val;
}

boolean c()
{
    boolean val = false;

    print( "calling b" );
    val = b();
    print( "b returned " + val );

    return val;
}

boolean d()
{
    boolean val = false;

    print( "calling c" );
    val = c();
    print( "c returned " + val );

    return val;
}

boolean main()
{
    boolean val = false;

    print( "calling d" );
    val = d();
    print( "d returned " + val );

    return val;
}

yields:

> abo.ash

calling d
calling c
calling b
calling a
in a about to retrieve_item
You need 1 more steaming evil to continue.
a returned false
b returned false
c returned false
d returned false
Interesting. That sure looks like a bug. It SHOULD abort the script.

Edit: Maybe not: we are capturing the result of the aborting function. Except we are in state EXIT. Hmm
 
Last edited:

Veracity

Developer
Staff member
OK. functions will unwind up to the point where you capture their value.

Code:
boolean a()
{
    print( "in a about to retrieve_item" );
    retrieve_item( 1, $item[ steaming evil ] );
    print( "in a after retrieve_item" );
    return true;
}

boolean b()
{
    print( "calling a" );
    a();
    print( "a returned" );
    return true;
}

boolean c()
{
    print( "calling b" );
    b();
    print( "b returned" );
    return true;
}

boolean d()
{
    print( "calling c" );
    c();
    print( "c returned" );
    return true;
}

boolean main()
{
    print( "calling d" );
    d();
    print( "d returned" );

    return true;
}
yields:

> abo.ash

calling d
calling c
calling b
calling a
in a about to retrieve_item
You need 1 more steaming evil to continue.
 

Donavin69

Member
This really seems to be how you first explained it...if there was no 'capture' at the end of the 'chain' the script would abort...it also seems that would be the desired result of a boolean expression.

Simply capturing the return from the returns from the separate booleans is required...this has been my experience with it as well (using both CLI and ASH, as expected)

I had created several small booleans to get around my issue of the cli command try; (and the try/finally not being in the master function list on the wiki) but I didn't know I could have an if () {} I thought the if statement must have an action. By using that format, I was able to drop the size of my breakfast script by about 100 lines...(and a lot of function calls)
 

Theraze

Active member
Well, and you can replace the 8 characters of "if () {}" with the one character "!" but... yeah, same results, different methods. There's a wide variety of things you can do to shorten up your code if you're in that sort of mood. :)

The if option is better if you're ever going to go back and actually do something with it. If you're just doing it and don't plan on caring about whether or not you got beaten up...
 

Donavin69

Member
Why does ! work? If it returns TRUE, it would be FALSE (!TRUE == FALSE (in a boolean expression)), which should crash...

The cases where I'm using it are things like I said, for stock lists, I don't really care if it fails, but its nice to know...and the output would already tell me that...
 

Theraze

Active member
Because regardless of the result, you ended up with success. It's sort of odd like that, in that mafia knows that a failed adventure result is bad, but a successful adventure result that turns false isn't actually an abortive result... eh, I don't know why it works, jasonharper, one of the major developers suggested using that instead of the if bit, and it works. :)
 
Top