Lite om 3.0 : ------------- Pär Winzell -- pw@lysator.liu.se -- Statik@SvenskMud. Tre stora nyheter i 3.0 är - 1. Typcheckning. 2. Multiple inheritance. 3. Förbättrad (!) arrayhantering. Typchecking fungerar ungefär som i C. Ger man en #pragma strict_types i filen utförs typchecking på hela den filen, annars utförs det på varje funktion som har en definierad typ. Man tjänar en hel del på att använda typchecking; programmen blir bra mycket snyggare och man hittar vissa fel direkt genom att de ger kompileringsfel. Observera att det inte finns några VARNINGAR i LPC. Typfel avbryter helt kompileringen och hamnar i /log/wizardname lika mycket som syntaxfel. Följande typer finns : void, status, int, string, object och mixed. Mixed är en specialtyp som kan vara vilken som helst av de andra typerna. Man typdeklarerar funktioner, argument till funktioner samt variabler - globala eller lokala. Som sagt är det typdeklarationen av funktionen som bestämmer om typkontroll utförs på resten av funktionen. Förutom typerna kan man deklarerar arrayer med *. Ett litet exempel på ovanstående : object * players_of_level_x_or_higher(int minimum_level) { int i; object *player_list; object *list_to_return; player_list = users(); list_to_return = ({ }); for (i = 0; i < sizeof(player_list); i ++) { if ((int)player_list[i]->query_level() >= minimum_level) { list_to_return += ({ player_list[i] }); } } return list_to_return; } Två kommentarer om detta : list_to_return() sätts till en tom array, efterssom den har värdet 0 från början, och man kan inte göra addition på en array och en nolla. Man skulle kunna skrivit : if ((int)player_list[i]->query_level() >= minimum_level) { if (list_to_return) { list_to_return += ({ player_list[i] }); } else { list_to_return = ({ player_list[i] }); } Andra kommentaren är att man måste cast:a en call_other(), i detta fall anropet till query_level(). Detta för att parsern omöjligt kan veta vilken typ en funktion i ett annat objekt har. Detta är det enda tillfälle då casting är nödvändigt som jag kan komma på just nu, förutom då man använder en variabel av typ mixed till ett väldeklarerat ändamål. Här kommer vi naturligt in på arrayer och de förbättrade funktioneran för detta. Addition av arrayen är en, som synes. Ovanstående funktion kan man skriva om snyggare med följande kod : status check_level(object what_ob, int minimum_level) { return (int)what_ob->query_level() >= minimum_level; } object * players_of_level_x_or_higher(int minimum_level) { return filter_array(users(), "check_level", this_object(), minimum_level); } filter_array() är en av ganska många nya funktioner som avsevärt snabbar upp och förenklar hanteringen av speciellt stora arrayer. Ovanstående anrop betyder : För alla element i users(), dvs alla spelare, anropa check_level() i this_object() med elementet samt minimum_level som extra argument, och om funktionen returnerar sant, inkludera elemtet i den array som filter_array slutligen ska returnera. \vriga arrayfunktioner just nu (3.0 är fortfarande en alfaversion - det kommer nyheter var och varannan dag) är : filter_, member_, slice_, unique_, map_, och sort_array. slice_array har från och med 3.0.50 syntaxen arrÄlow .. highÅ. Dokumentation bör finnas på dessa i /doc/efun. Mest använda är nog slice_array som tar bort en bit ur en array, member_array som letar efter ett element i en array och returnerar dess index eller -1 om elementet inte finns, filter_array som har ovanstående funktion samt map_array som "översätter" objekt till någon egenskap hos dem. Se dokumentationen. :) Slutligen multiple inheritance - detta innebär helt enkelt att man kan ärva mer än en fil, vilket var omöjligt i 2.x. Till exempel kan vi ju ta den eminenta libfun som kan tänkas behövas lite här och där : inherit "obj/funlib"; inherit "room/room"; < KOD > Hur ärvning av objekt fungerar går jag inte in på här. För de som vet : Det kan tänkas att samma funktionsnamn existerar i mer än ett av de ärvda objekten. I vanliga fall kommer man åt funktioner i ärvda objekt med ::-operatorn : void reset(status arg) { ::reset(arg); } till exempel. Har vi nu ärvt flera filer får vi göra : inherit "objekt1"; inherit "objekt2"; void reset(status arg) { objekt1::reset(arg); objekt2::reset(arg); } Det enda problem som kan uppstå är om två filer har samma namn OCH man ska komma åt samma funktioner i båda. Förhoppningsvis inträffar ej detta. :) Lycka till med programmeringen. 3.0 är kul! / Pär.