Geas MUD, enter the Aventure!
Geas Home | Play the Game

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.1.3 Complex function applications

With the previous chapters in memory, the interesting question becomes 'What can you put into one of these function calls?'. The answer is 'Practically anything!', it's just a matter of knowing how to write the code in the right way (as usual).

The tricky bit usually is operators. For most of them you use the special keyword operator to encapsulate the actual operator. The operators that can be encapsulated are +, -, *, /, %, &, |, ^, >>, <<, <, >, <=, >=, ==, !=, []. For the []-operator you then have to index it in order to make use of it, but more about that later.

Often enough you want to perform one operation and then send the result to another one. You do that with the @-keyword, but beware that execution is right-to-left on that line, and that you'll have to figure relational operators that way too!

This all sounds a bit difficult to understand, but let me give you an example to make everything clear:

Assume you have an array like this representing some player names:

string *arr = ({ "Bocephus", "Thurol", "Elessar", "Budwise",
                  "Akhan", "Logg" });

Now assume you want to filter out the names that are more than five characters long. Usually this involves running a loop over the contents of the array, examining each entry in turn to determine its invidual length, and finally building an array containing the result.

string *
func(string *arr)
    int i, sz;
    string *result = ({});

    for (i = 0, sz = len(arr); i < sz; i++)
        if (strlen(arr[i]) > 5)
            result += ({ arr[i] })

    return result;

Naturally, this could be sorted with the efun filter:

filterfunc(string item)
    return strlen(item);

string *
func(string *arr)
    return filter(arr, filter_func);

But that requires me to write a separate function for the filter. No, a much more pratical solution is one that goes into a single line, like this:
// ... in actual code defining arr

result = filter(arr, &operator(<)(5) @ strlen);

NB! Pay special attention to the operator here, notice that since the parsing is done right-to-left, the operator used is < as the expression becomes 5 < strlen(name).

Now assume you want to complicate matters; you want to find out whom of the filtered people are mortals. Well, simple.. let's just add to the expression:

// ... in actual code defining arr

result = filter(filter(arr, &operator(<)(5) @ strlen), 
                &operator(==)(0) @ SECURITY->query_wiz_rank);

As you can see, I just expanded the entry with a filter-call to process the results of the first.

Ok, let's try something slightly more difficult. What will this line do when you put it on the screen?

exec return implode(sort_array(map(filter(users(), sizeof @ 
                    &filter(, &call_other(, "id", "shield")) @ 
                    deep_inventory)->query_real_name(), capitalize)), ", ");

Well now, that wasn't too difficult, now was it?

First, I loop through all users and look through their entire inventories. I filter out those users who are carrying a shield, and obtain their names. The resulting array I then sort, capitalize and paste together into a string with a , in between each name. Finally I return the resulting string.

In other words, I obtain a list of all users who are carrying a shield.

NB! Now it is time for a warning. As you can see from the previous example, I had no trouble at all generating a list of objects that probably reached into the thousands before starting to narrow things down. Let me check... Yes, in this case more than 1500 objects, all being called to see if they match the name "shield" and then other on top of that further operations applied to the resulting lists. Obviously it's very easy to generate massive calls which tax the computer quite a lot.

What this warning amounts to really is to think before you code, so that you won't bog down the computer with lots of calls that perhaps aren't strictly necessary.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by Ronny Wikh on July, 8 2003 using texi2html