Object-oriented ASH

StDoodle

Minion
Forgive the title, but I can't seem to think of a better description; though it may be fairly accurate.

Currently, my Daily Deeds script has separate functions for grabbing the default, max, and sometimes current use numbers on different settings. Ie def_REAGENT() checks to see if you have Advanced Saucecrafting, and returns 1 if you do, 0 otherwise (this number controls whether or not the script should report on reagent summoning). Then I have max_REAGENT() set to look for Way of the Sauce & the combination of being a Sauceror & having the nemesis item as well, and then report the maximum number of reagents one can summon based on those.

What I'd like is to have one place to put all of this information for each setting. I was hoping for a way to put this all in a record, and then users would normally only need to update the text file containing said data. However, I can't figure a way to define functions in a record. I'm not sure it's possible; it looks as if the best I can do is to use "call," but then the script would still need a separate function built-in.

Barring the above, it looks like my best bet is to have a "master function" for each setting, which takes a single string parameter. That string could then be used in a switch statement to control which number to report. However, seeing as I'd like to return different datatypes, this doesn't seem all that ideal; I'd have to have several functions to handle the overloading, and I'd end up with nearly as much "clutter" as my present implementation.

For reference, my goal is to refactor the script in such a way as to have all of the display logic be setting-agnostic. Not a huge deal now, but it will make a difference when I add in support for several new features via the relay browser. What I'd like is to be able to go to one chunk of code for each setting, not having to hunt all over and update in each place. It's looking like the best way to do that will simply be to organize all of the relevant functions by setting, but still ending up with multiple functions for each. This is workable, but I'd like to know if anyone has any thoughts on a better approach before I do a lot of re-writing of my code.

Thanks everyone for your help!
 

heeheehee

Developer
Staff member
I don't know why, but I seem to be a fan of the long, confusing lines of code, like
Code:
int max_REAGENT() {
    return have_skill($skill[advanced saucecrafting]).to_int()*(3+2*have_skill($skill[the way of sauce]).to_int()+3*(item_amount($item[gravyskin belt of the sauceblob])>0 && my_class()==$class[Sauceror]).to_int());
}
for max_REAGENT(), testing if it's greater than 0 or not. I guess it's just easier on my brain to have just one function (line?) per setting. (Not exactly helping with the whole "clutter" issue, though...) Then again, I haven't had any formal training with coding (yet), so that's probably not the best way to go about things like this.

Regarding storing functions in a record: ZLib's eval() function seems useful, but I'm almost entirely sure that's not what you're looking for. To be honest, though, I'm not entirely sure what you're looking for. call might work, but as you've noted, the function would have to be predefined in the script.
 

StDoodle

Minion
Yeah, what I'm really looking for is a way to define functions such that they can be read in and out of files via file_to_map() and map_to_file(). I don't think there's a meaningful way to do so, without adding a huge amount of complexity and hackiness, but I just wanted to check in case there's something simple I'm missing.
 

StDoodle

Minion
Re: call

Yeah, it's funny 'cause that was what gave me the kick to create the "Misc. ASH Features" page in the first place... just never got around to adding it.

Anyway, I figured this would be how it would end up; I didn't think I was missing any major features / abilities, but like I said, wanted to double-check before rewriting the whole script in question.
 

philmasterplus

Active member
@StDoodle: Perhaps you're looking for namespaces (not KoLmafia namespaces, but C(++)-style ones). A decent compromise would be to create a dummy record with an obscure type name, create a dummy object with the "namespace," and make these functions accept two arguments:

PHP:
record __REAGENT__
{
	#Does KoLmafia allow blank records? I don't know.
} REAGENT;

boolean has_one( __REAGENT__ r );
int max( __REAGENT__ r );
string summon( __REAGENT r , int arg );

Then you would be able to call these functions "Java-style":
PHP:
REAGENT.has_one();
REAGENT.max();
REAGENT.summon( 3 );

As long as you give a sufficiently obscure type name to your record, it wouldn't cause any clash problems. You could even save actual data in these records for the functions to interact with.
 

StDoodle

Minion
phil, that's actually fairly close to what I ended up doing in the end. I defined a custom record that records everything you could need to know about each daily deed, and then for each built-in deed I have a function that returns that record with all of the relevant info.
 
Top