Calling functions

> verify amultis

Function 'primary( )' undefined. This script may require a more recent version of KoLmafia and/or its supporting scripts. (amultis.ash, line 8)

This whole function calling thing is confusing me. I've previously avoided having multiple functions in scripts that I've made, but I figure it's something I should probably learn. I tried the wiki, but didn't find anything after some cursory searches. This is just a script to log in derelict accounts that are holding basement clans, to prevent miscreants from sneaking in and taking leadership. I figured I may as well throw in some summons, increasing the supply of consumer goods seems harmless enough, and who knows when these accounts might be repurposed and need a little meat.

Code:
import <recordsongs.ash>;
import <still_automator.ash>;

boolean[string] starter;
starter["pleasure slave"] = true;

int tomeLeft = 3 - get_property("_clipartSummons").to_int();

if (starter[my_name()]) main();

void main()
	{
if 
primary();
sinsonte();
cli_execute("login wandering multi");
primary;
domesticated;
cli_execute("login magician");
primary();
calcutta();
cli_execute("login lame joke multi");
primary();
recordsongs();
    }
    
Void primary()
    {
cli_execute("breakfast");
if ( tomeLeft > 0 ) && (have_skill($skill[Summon Clip Art]) create( tomeLeft, $item[ Potion of punctual companionship ] );
cli_execute("mallsell * punctual @8500 limit 1");
    }
    
Void sinsonte()
	{
	cli_execute("acquire 10 bottle of tequila");
	call still_automator.ash;
	cli_execute("mallsell * sinsonte @2300");
	}
	
Void calcutta()
	{
	cli_execute("acquire 10 bottle of gin");
	call still_automator;
	cli_execute("mallsell * calcutta @2300");
	}
	
Void domesticated()
	{
	cli_execute("acquire 10 bottle of whiskey");
	call still_automator;
	cli_execute("mallsell * domesticated @2300");
	}
 

Winterbay

Active member
I think the problem with that is that you have the functions after main(), anything after that is basically ignored and so is never defined and cannot be called. You need to list the functions above main(). Also you cannot encapsulate main() in an if-statement, you need to do that within main itself.

AlLso, the functions within the imported scripts needs to be called by name, you cannot call the entire scritp in that way. If you want to do that you do not need to import it but can instead use cli_execute("call scriptname.ash");

Edit: Also, I'm am fairly certain that calling login in that way will fail in possibly humorous ways.
 
Last edited:

Bale

Minion
I don't see anything wrong with how he calls login. It will automatically logout if he is already logged in.

About this...
import <still_automator.ash>;
call still_automator.ash;

When you import still_automator it will run all the commands that are not in functions. If you don't want something to be executed simply by importing, then you need to put it in a function. Then when you want to use a function from that script, you call it just like you call functions in your current script. I suspect that still_automator needs a serious re-write before it can be imported usefully.
 

Veracity

Developer
Staff member
I think the problem with that is that you have the functions after main(), anything after that is basically ignored and so is never defined and cannot be called.
No. When we parse a file, we notice the "main" function by name. It is not "the last function in the file".

There are numerous syntax errors in what he posted. But he has fixed them, so, cool.
 

Winterbay

Active member
I don't see anything wrong with how he calls login. It will automatically logout if he is already logged in.

Yes, but I thought that would also abort script execution, but apparently not.

No. When we parse a file, we notice the "main" function by name. It is not "the last function in the file".

There are numerous syntax errors in what he posted. But he has fixed them, so, cool.

Ahh right, yet another thing learned today :)
 

Catch-22

Active member
It's generally considered good practice to declare your functions in the code before using them though, even if the interpreter doesn't care. The same is true for imports, even though you could theoretically put them anywhere within the global context.
 

Bale

Minion
In ash, you can not put imports anywhere — you can only put them at the beginning of the script. Similarly ash requires you to declare functions before they can be used although you can cheat by defining the function after its declaration.
 

Veracity

Developer
Staff member
The key point is that you must "declare" the functions before you use them. You generally do that by simply "defining" the function - putting in the whole function - but you can't do that for mutually recursive functions, so ASH allows "forward declarations". That is not "cheating".

You COULD have a bunch of forward declarations, then main(), and then the function definitions. Not recommended, but it is possible...
 

Bale

Minion
Consider me properly scolded about "cheating." 90% of the time I see forward declarations it is because of poor script organization, not because it was actually necessary. That annoys me even though it isn't "cheating."
 

Veracity

Developer
Staff member
Fair enough. Forward declarations should only be used when they are technically required. I agree that defining functions before you use them and putting main() at the end makes for clearer code. And code clarity is #1, in my opinion. :)
 
I didn't know ASH supported forward declaration! Awesome. I take it it works like this:
Code:
type name(args);
...
type name(args){
stuff
}
Or is it different?
 
Top