LPC (programovací jazyk)
Paradigma | multiparadigmatický, objektový, funkcionální, procedurální, prototypový |
---|---|
Autor | Lars Pensjö |
Vývojář | Lars Pensjö, Jörn Rennecke, Felix Croes, Tim Hollebeek, Lars Düning a další |
Typová kontrola | slabá statická, silná dynamická |
Hlavní implementace | LPMud |
Dialekty | Amylaar, MudOS, FluffOS, LDMud, DGD, SWLPC |
Ovlivněn jazyky | C, C++, Lisp, Perl |
Ovlivnil jazyky | Pike |
Web | lpmuds.net |
LPC je objektově orientovaný programovací jazyk, vyvinutý původně Larsem Pensjöem (podle něho iniciály LP) na základě jazyka C. Původně byl určen především k programování MUDů, jeho snadnost a všestrannost však vedla k jeho používání i mimo tuto oblast a ke vzniku nových a samostatně se dále vyvíjejících implementací, z nichž nejrozšířenější je známa jako programovací jazyk Pike.[1]
Struktura jazyka
LPC je strukturou velmi podobný programovacím jazykům C a C++. Je objektově orientovaný, ale neužívá pojmu třídy. Počítačový program se skládá z programů jednotlivých objektů; některé z nich se pak vyskytují jedinečně, zatímco jiné fungují jako prototypy (blueprint), z nichž se vytvářejí klony (clone). Jedinečné objekty a prototypy jsou uloženy v oddělených souborech (zpravidla s příponou .c
) v adresářové struktuře programové knihovny (mudlib), odkud je v případě potřeby LP ovladač (driver) načítá do paměti a kompiluje, a v případě nepotřeby z paměti opět odstraňuje.
Program se spouští načtením a kompilací řídicího objektu (master object); ten pak načte do paměti další objekty, jejichž přítomnost je pro běh programu bezpodmínečně nutná. Další objekty, které podle průběhu programu mohou, ale nemusí být zapotřebí, se načítají nebo klonují z prototypů na základě požadavků jiných objektů.
Programový kód objektů se skládá z deklarací globálních (v rámci celého objektu platných) proměnných a z popisu funkcí. Proměnné definují vlastnosti (atributy) objektu, některé z funkcí vystupují navenek jako metody, jimiž spolu objekty navenek komunikují. Proměnné jsou zvenčí objektu přístupné zpravidla jen pomocí k tomu určených metod (v LPC tradičně odlišovaných předponami set_
a query_
).
Všechny klony jednoho objektu mají k dispozici stejné metody a stejné proměnné (které samozřejmě mohou mít různý obsah). Objekty mohou dědit vlastnosti a metody jiných objektů stejným způsobem, jako je dědí třídy v programovacích jazycích, které pojem třídy používají. Většina implementací LPC navíc umožňuje stínění (shadowing), kdy mohou metody jednoho objektu překrýt metody jiného objektu, takže se zastíněný objekt navenek (přechodně) chová jinak, aniž je sám nějak změněn.
Protože jazyk LPC byl původně navržen pro programování MUDů, počítá se s tím, že herní objekty (hráči, nehráčské postavy, předměty, místnosti) jsou objekty též v LPC, pročež se mohou vzájemně obsahovat (stojí-li hráč v místnosti a má s sebou svačinu v batohu, pak objekt místnosti obsahuje objekt hráče, objekt hráče obsahuje objekt batohu a objekt batohu obsahuje objekt svačiny), být někde spolupřítomny a podle toho si vzájemně nabízet různé metody (např. hráč může hovořit s postavou přítomnou v téže místnosti). Standardním konstruktorem je create()
, které v mnoha případech může být jedinou metodou explicitně popsanou v objektu (další metody pak objekt dědí z prototypu):
inherit "/i/room"; // tímto zdědíme proměnné a funkce prototypu místnosti
void create()
{
// nejdříve spustíme konstruktor definovaný v prototypu:
::create();
// a poté nastavíme některé zděděné proměnné:
set_short("V obyčejné místnosti");
set_long("Nacházíš se v obyčejné místnosti, na které není vůbec, "
"ale vůbec nic zvláštního. Ale aspoň to tu voní.");
set_smell("Hm, voní to tu hezky.");
set_exit("sever","/room/example");
}
Odkaz na "/i/room"
v uvedeném příkladu není v LPC obecně platný, stejně jako například funkce set_smell()
. Jsou to vlastnosti konkrétní mudové knihovny, která v tomto případě obsahuje prototypový soubor místností na adrese "/i/room.c"
v rámci svého adresářového stromu, a která v tomto prototypu (nebo některém souboru jím děděném) definuje funkci set_smell()
. Charakter konkrétní implementace LPC je tak z velké části dán používanou mudovou knihovnou. Každá implementace má přinejmenším svou základní mudovou knihovnu, často však konkrétní MUDy nebo skupiny MUDů pracují s mnohem rozsáhlejšími vlastními knihovnami, které umožňují jemnější zacházení s herními objekty a řízení průběhu hry.
Ahoj světe
Vzhledem k charakteru LPC není možné říci „Ahoj světe“ jednoznačným způsobem. Program nemá výstup ve vlastním smyslu slova; výstup pro uživatele programu (tedy zpravidla hráče MUDu) je zprávou, kterou některý z objektů poslal interaktivnímu objektu, který ztělesňuje uživatele.
Nejjednodušším výstupem je poslání zprávy při vytvoření objektu, a to interaktivnímu objektu, který vytvoření způsobil:
void create()
{
write("Ahoj, světe!");
}
Má-li být zpráva odeslána uživateli, který se právě s objektem setkal (tedy ocitl se s ním v téže místnosti, objekt se ocitl v něm samotném nebo on sám se ocitl v objektu), je nutno zavolat funkci write()
ve funkci s vyhrazeným názvem init()
. Má-li být zpráva odeslána po zadání určitého hráčského příkazu, pak je nutno tento hráčský příkaz ve funkci init()
přiřadit určité funkci, a v té potom zavolat write()
.
Kromě write()
obsahuje LPC standardně ještě výstupní funkce printf()
(funguje jako write()
, ale umožňuje složitý formátovaný výstup), say()
(pošle zprávu všem dalším objektům přítomným v téže místnosti jako vysílající objekt), tell_object()
(pošle zprávu danému objektu) a tell_room()
(pošle zprávu všem objektům nacházejícím se v dané místnosti). Mnoho mudových knihoven však nabízí sofistikovanější a programátorsky výkonnější funkce pro předávání zpráv. Vyslání zprávy hráči v reakci na jeho příchod do místnosti, v němž se nachází vysílající objekt, pak může vypadat třeba takto (příklad použitelný například v knihovně mudu UNItopia nebo Prahy):
inherit "/i/item/message";
#include <message.h>
void init()
{
send_message_to(this_player(),MT_NOTIFY,MA_MOVE_IN,wrap("Ahoj, hráči!"));
}
void create()
{
// tady by v reálu něco bylo, ale pro tento příklad nás to nezajímá
}
Datové typy
- Objekt (object)
- Typ dostupný ve všech implementacích. Proměnná typu objekt obsahuje paměťový ukazatel na libovolný objekt (ať už prototyp, nebo klon), který se účastní běhu programu (tedy jak prototyp, tak klon). Konstanta tohoto typu se nedá zapsat, je možné jen řetězcem popsat soubor, ze kterého byl objekt vytvořen, nebo opět řetězcem popsat jednoznačné jméno objektu:
object ob1 = touch("/apps/database"); // vytvoření jedinečného objektu
// ze souboru /apps/database.c
object ob2 = clone_object("/obj/batoh"); // vytvoření klonu (pokud dosud nebyl
// vytvořen prototyp, pak se nyní vytvoří)
- Celé číslo (int)
- Typ dostupný ve všech implementacích, zpravidla jako 32bitové celé číslo se znaménkem, v některých implementacích jako číslo 64bitové. Konstanta se zapisuje jako běžné celé číslo s případným znaménkem.
int cislo1 = 789;
int cislo2 = -45;
- Desetinné číslo (float)
- Typ dostupný ve všech implementacích, většinou jako 32bitové číslo s pohyblivou řádovou čárkou. Konstanta se zapisuje jako celočíselná a desetinná část oddělené tečkou s případným předsazeným znaménkem.
float pi = 3.1415;
- Řetězec (string)
- Typ dostupný ve všech implementacích. Řetězec znaků o proměnné (prakticky libovolné) délce. Konstanta se zapisuje jako text uzavřený do programátorských uvozovek (případné programátorské uvozovky se do textu zapisují jako dvojznak
\"
).
string text = "Nějaký pěkný textík.";
- Smíšená hodnota (mixed)
- Typ dostupný ve všech implementacích. Proměnná tohoto typu může nabývat hodnot různých typů, což v praxi znamená vypnutí typové kontroly pro tuto proměnnou.
mixed anything = 13.56;
anything = 333;
anything = "blablabla";
- Pole (*|array)
- Typ dostupný ve všech implementacích. Pole (seznam) hodnot jiného typu o proměnném (prakticky libovolném) počtu prvků. Deklaruje se zpravidla pomocí modifikátoru
*
za označením typu obsažených hodnot, tedy např.object *, string *, int *
, jen v implementaci MudOS pomocí modifikátoruarray
(modifikátor*
je však rovněž přípustný). Modifikátor nemůže být skládán, tedy případné pole polí je nutno deklarovat jakomixed *
, tedy pole smíšených hodnot. Konstanta se zapisuje jako seznam hodnot oddělených čárkou (s volitelnou čárkou i za poslední hodnotou) a ohraničený dvojznaky({
a})
.
int * cisla = ({ 1, 2, 3 });
string * retezce = ({ "ble", "bla", "blu" });
mixed * vsechno = ({ 1, "text", -56.5, ({ "podpole", 2 }) });
- Asociativní pole (mapping)
- Typ poskytovaný téměř všemi implementacemi, neuspořádané pole klíčů, k nimž jsou přiřazeny hodnoty. Konstanta se zapisuje jako seznam přiřazení mezi klíčem a hodnotou oddělený čárkami (s volitelnou čárkou po posledním přiřazení) a uzavřený do dvojznaků
([
a])
, přičemž přiřazení se zapisuje jako klíč a hodnota, oddělené od sebe dvojtečkou. Klíčem mohou být zpravidla všechny jednoduché typy (čísla, řetězce, objekty), hodnotami všechny typy. Některé implementace umožňují vícenásobná asociativní pole, tedy přiřazení více hodnot každému klíči (ale všem klíčům týž počet) — pak se jednotlivé hodnoty oddělují středníkem.
mapping tabulka = ([
"jméno" : "Josef",
"příjmení" : "Novák",
"výška" : 183,
"děti" : ({ "Marie", "Anna", "Jan" }),
]);
- Klauzura (closure|function)
- Typ podporovaný implementacemi Amylaar LPMud, LDMud, MudOS a některými dalšími, v MudOSu deklarovaný klíčovým slovem
function
, v ostatních implementacích klíčovým slovemclosure
. Jedná se o ukazatel na funkci nebo samostatnou a vůči objektu uzavřenou část kódu, kterou je pak možno například předávat jako parametr dalším funkcím nebo sdělovat jiným objektům. Konstanta se zapisuje buď jako dvojznak#'
následovaný jménem lokální (v objektu definované) funkce, nebo jako úsek kódu uzavřený do dvojznaků(:
a:)
, nebo jako funkcelambda()
, umožňující zápis výrazů, které je nutno vyhodnotit při každém výskytu znova, v lambda kalkulu. MudOS podporuje pouze druhý typ zápisu, Amylaar LPMud a LDMud všechny tři.
closure c1 = #'query_je_to_k_necemu;
closure c1 = (: $1->query_invis()?"Někdo":$1->query_short() :);
closure c1 = lambda( ({ 'a, 'b }), ({ #'>, 'a, 'b }) );;
- Symbol (symbol)
- Typ podporovaný implementacemi, které umožňují konstrukci lambda klauzur (zejména Amylaar LPMud a LDMud), v nichž symboly zastupují proměnné obdobně, jako klauzury zapsané pomocí
#'
zastupují funkce. Konstanta se zapisuje jako programátorský apostrof následovaný jménem symbolu.
symbol var = 'x;
- Chráněné pole (quoted array)
- Typ podporovaný v implementacích, které umožňují vytváření lambda klauzur, v nichž má běžně zapsané pole význam vložené funkce. Aby bylo možno používat v rámci lambda zápisu pole, je nutno je odlišit buď uzavřením do funkce
quote()
, nebo v případě konstant předsazením programátorského apostrofu. Typ nemá žádné vlastní klíčové slovo pro deklaraci, chráněná pole proto musí být deklarována jakomixed
.
mixed nedopole = '({ 1, 2, 3 });
- Záznam (class|struct)
- Typ podporovaný v implementacích LDMud od verze 3.3 a MudOS. V LDMudu se deklaruje klíčovým slovem
struct
, v MudOSu klíčovým slovemclass
. Umožňuje sdružení několika proměnných různých typů do jednoho záznamu.
struct udalost {
int rok;
string nazev;
};
struct udalost napr = (<udalost>);
napr->rok = 1415;
napr->nazev = "Upálení Mistra Jana Husi";
| class udalost {
int rok;
string nazev;
};
class udalost napr = new(class udalost);
napr->rok = 1415;
napr->nazev = "Upálení Mistra Jana Husi";
|
- Stav (status)
- Typ zavedený do některých implementací jako forma typu boolean (přičemž true a false jsou zastoupeny celočíselnými hodnotami 1 a 0), většinou ovšem jen jako synonymum typu
int
, tedy bez významu pro funkčnost jazyka. V pozdějších verzích implementací sestatus
zpravidla označuje za zastaralý typ, jejž není vhodné používat.
status flag = 1;
Funkce
Běh programu v LPC spočívá zpravidla v reakcích na interaktivní vstupy uživatelů (tj. v případě MUDu hráčů). Reakce spočívají ve spouštění funkcí, přiřazených určitým uživatelským akcím, v objektech, s nimiž se uživatel nějakým způsobem dostal do kontaktu (v případě MUDu se jedná například o vstup do místnosti, v níž se objekt nachází). Tyto akcím přiřazené funkce pak mohou spouštět funkce v daném objektu přímo nebo se zpožděním, volat funkce v jiných objektech, žádat ovladač o provedení vestavěných funkcí, případně vytvářet další objekty, které mohou následně vykonávat další funkce. Běh programu se tedy skládá z vykonávání funkcí volaných jednotlivými objekty.
Funkce musí být vždy volána z nějakého objektu. Podle toho, kde je volaná funkce definována, se pak rozlišují tři základní případy:
- Lokální funkce objektů (lfun)
- Funkce definované v objektech samotných, resp. v jejich prototypech (klony mají k dispozici tytéž funkce jako jejich prototyp), napsané v LPC. Volá-li se lokální funkce v jiném objektu, volá se pomocí vestavěné funkce
call_other()
, resp. jejího zkráceného zápisu->
(call_other(obj,nejakafunkce,par1,par2);
, resp.obj->nejakafunkce(par1,par2)
). Volá-li se lokální funkce v témže objektu, volá se buď prostým jménem funkce a parametry (nejakafunkce(par1,par2);
), nebo pomocícall_other()
, přičemž na objekt samotný se odkazuje vestavěnou funkcíthis_object()
(call_other(this_object(),nejakafunkce,par1,par2);
, resp.this_object()->nejakafunkce(par1,par2)
). Je-li v objektu překryta lokální funkce zděděného objektu, je možno volat původní zděděnou funkci pomocí operátoru::
(tedy::prekrytafunkce()
, resp. v případě více děděných objektů pro jednoznačnostzdedenyobjekt::prekrytafunkce()
).
- Vestavěné funkce (efun, kfun)
- Vestavěné funkce (ve většině implementací označované zkratkou efun z „externí funkce“, v implementaci DGD kfun z „kernelová funkce“) jsou definovány přímo v ovladači, tedy napsány v jazyce C a zakompikovány do ovladače, který je dává k dispozici všem objektům. Jako takové jsou volatelné odkudkoli prostým jménem funkce a parametry (
nejakafunkce(par1,par2);
), případně, pokud byla nějaká vestavěná funkce překryta lokální nebo druhotně vestavěnou funkcí, pomocí operátoruefun::
(tedyefun::nejakafunkce(par1,par2);
).
- Druhotně vestavěné funkce (simul_efun, sefun, auto)
- Druhotně vestavěné funkce (ve většině implementací označované jako simul_efun nebo sefun ze „simulované externí funkce“, v implementaci DGD označované jako auto z „automaticky děděné funkce“) jsou naprogramovány v LPC v rámci programové knihovny určité implementace nebo konkrétního MUDu a umístěny do speciálního objektu, jehož funkce ovladač dává k dispozici všem objektům stejně jako funkce vestavěné, resp. (v případě DGD) jejž ovladač považuje za automaticky děděný do všech dalších objektů. Tyto funkce se pak volají stejně jako vestavěné funkce prostým jménem funkce a parametry (
nejakafunkce(par1,par2);
).
Typové modifikátory
- void
- Používá se jako zástupce typové deklarace v případě funkcí, které nevracejí žádnou hodnotu. Je k dispozici ve všech implementacích.
- varargs
- Modifikátor pro deklarace funkcí, poskytovaný většinou implementací. V případě použití modifikátoru se počet parametrů funkce bere jako fakultativní, tedy parametry zvenčí předané funkci se doplní nulami do počtu celkem deklarovaných parametrů. V některých implementacích je rovněž možno použít
varargs
u deklarace posledního parametru; pak je možno funkci předat více parametrů, než bylo deklarováno, a poslední parametr uvnitř funkce vystupuje jako pole, které všechny tyto parametry obsahuje.
- private
- Modifikátor pro deklarace funkcí a globálních (tedy v celém objektu platných) proměnných, specifikující, že funkce nebo proměnná není dostupná odjinud, než z objektu, v němž je deklarována, tedy ani v objektech, které tento objekt dědí. Je k dispozici ve většině implementací.
- protected
- Modifikátor pro deklarace funkcí, dostupný v mnoha implementacích. Deklaruje, že funkci je možno volat jen ze samotného objektu a z objektů, které tento objekt dědí, a to jen interním voláním lokální funkce, nikoli však pomocí
call_other()
či jinými způsoby.
- static
- Modifikátor dostupný ve většině implementací, který v případě funkcí deklaruje, že funkci není možno volat z jiných objektů. Volání ze samotného objektu i z objektů, které tento objekt dědí, je však možné jak interním voláním lokální funkce, tak voláním pomocí
call_other()
, tak voláním jinými způsoby (zpožděný procese spuštěnýcall_out()
, čekání na vstup pomocíinput_to()
apod.). V případě proměnných, pokud je povolen, má stejný význam jakonosave
.
- nosave
- Modifikátor pro deklarace proměnných a dědičnosti, dostupný v mnoha implementacích. Deklaruje, že proměnná se nemá ukládat při ukládání stavu objektu (serializaci).
- nomask
- Modifikátor pro deklarace funkcí, dostupný ve většině implementací. Deklaruje, že funkci není možno ani překrýt v objektech, které dědí tento objekt, ani zastínit jiným objektem.
- public
- Modifikátor dostupný ve většině implementací. V případě funkcí i proměnných deklaruje, že funkci či proměnnou není možno v objektu, který dědí tento objekt, předeklarovat jako
private
,static
neboprotected
, resp. že taková deklarace nebude účinná a funkce či proměnná bude nadále plně přístupná.
- virtual
- Modifikátor pro deklarace dědičnosti, dostupný v mnoha implementacích. Deklaruje, že proměnné děděného objektu se mají dědit pouze v případě, že nejsou již zděděny jinou větví dědičnosti.
- deprecated
- Modifikátor dostupný v LDMudu od verze 3.5, deklarující, že funkce nebo proměnná je zastaralá a neměla by být nadále užívána. Jakékoli užití dotyčné funkce nebo proměnné pak vydá varování.
Předávání parametrů
Parametry jednoduchých datových typů (celé či desetinné číslo, řetězec, stav) se v běžném případě předávají hodnotou, ale je možné též předávání odkazem (které se nestanovuje už v deklaraci, nýbrž operátorem &
až při volání funkce). Strukturované typy (objekt, pole, asociativní pole, klauzura, záznam) se předávají vždy odkazem. Díky tomu je zacházení s těmito typy rychlejší a úspornější, ale nese s sebou bezpečnostní riziko, které je nutno programátorsky ošetřit: Aby takto nebyla volanou funkcí změněna hodnota proměnné, kterou volaná funkce měnit nesmí, je potřeba v těchto případech nejprve vytvořit kopii hodnoty v jiné proměnné, a tu teprve předat volané funkci.
Řídicí struktury
- složený příkaz
- Příkazy se vykonávají postupně v pořadí, v jakém jsou uvedeny v programu. Jednoduchý příkaz je zakončen středníkem. Složený příkaz vzniká uzavřením několika příkazů do složených závorek. Výsledná konstrukce se potom vůči dalším řídicím strukturám chová jako jediný příkaz, jehož vykonání znamená postupné vykonání všech obsažených příkazů. Složené příkazy je možno opět skládat.
- if/else
- Základní řídicí struktura umožňující podmíněné vykonávání příkazu a větvení algoritmu. V případě splnění podmínky, tedy pokud má výraz uvedený jako podmínka po vyčíslení nenulovou hodnotu, se provede následující příkaz. V případě nesplnění podmínky se provede příkaz následující po bezprostředně následujícím
else
, nebo žádný příkaz, pokudelse
nenásleduje.
if (environment()->query_prsi())
{
do_command("obuj si holínky");
do_command("rozevři deštník");
}
else
do_command("dej deštník do batohu");
- switch
- Řídicí struktura umožňující vícenásobné větvení. Výraz uvedený jako podmínka se vyčíslí, a pak se uvnitř následujícího složeného příkazu porovnává s hodnotami uvedenými v jednotlivých úsecích
case
. Pokud se hodnota najde, pokračuje se ve vykonávání po hodnotě následujících příkazů. Pokud se hodnota nenajde, pokračuje se za klíčovým slovemdefault
, pokud se toto ve stávajícím složeném příkazu vyskytuje, nebo za stávajícím příkazem, pokud se v němdefault
nevyskytuje.
switch (player->query_invis())
{
case V_VIS:
write("Je tu nějaký hráč.\n");
break;
case V_NOLIST:
write("Po chvilce rozhlížení si všimneš, že je tu nějaký hráč.\n");
break;
case V_HIDDEN:
write("Máš pocit, že je tu někdo schovaný.\n");
break;
default:
write("Máš pocit, že tu někdo je, ale nikoho nevidíš.\n");
}
- for
- Základní podoba cyklu v LPC. Jako řídicí parametry se uvádějí tři výrazy (z nichž první může být též seznamem výrazů oddělených čárkami) oddělené středníky. Při startu cyklu se vyčíslí první výraz (respektive seznam výrazů), nejčastěji přiřazení výchozí hodnoty řídicí proměnné cyklu. Pak se vyčíslí druhý výraz, a pokud je nenulový, provede se následující příkaz a vyčíslí se třetí řídicí výraz. V opakovaném vyčislování druhého výrazu, provádění následujícího příkazu a vyčislování třetího výrazu se pokračuje, dokud druhý výraz nenabude nulové hodnoty.
for (i=0; i<sizeof(predmety); i++)
{
predmety[i]->remove();
write("Další předmět se rozpadl!\n");
}
- foreach
- Provede následující příkaz postupně pro všechny prvky předaného pole nebo asociativního pole. Hodnota prvku pole nebo asociativního pole se vždy nejprve přiřadí uvedené řídicí proměnné, takže je možno s prvkem pracovat v rámci příkazu.
foreach (object ob:predmety)
{
ob->remove();
write("Další předmět se rozpadl!\n");
}
- while
- Cyklus s kontrolou podmínky na počátku. Uvedený výraz se vyčíslí, a pokud je jeho hodnota nenulová, provede se následující příkaz. To se opakuje tak dlouho, než výraz dosáhne nulové hodnoty.
while (environment(npc)->is_dangerous())
{
write("Tady není bezpečno!\n");
npc->random_move();
}
- do/while
- Cyklus s kontrolou podmínky na konci. Provede se daný příkaz, a poté se vyčíslí výraz. Dokud je výsledná hodnota výrazu nenulová, postup se opakuje.
do
{
npc->random_move();
do_command("řekni Kde jen mohou ty housle být?\n");
}
while (!present("housle",environment(npc)))
do_command("řekni Aha, tady!\n");
- break
- Vyhrazený příkaz
break
, je-li použit v cyklu, způsobí okamžité ukončení nejbližšího cyklu a pokračování prvním příkazem za cyklem. Je-li použit v konstrukciswitch
, pak způsobí okamžité pokračování prvním příkazem za touto konstrukcí (viz příklad uvedený výše u konstrukceswitch
).
- continue
- Vyhrazený příkaz
continue
, je-li použit v cyklu, způsobí okamžité ukončení současného průběhu nejbližšího cyklu a zahájení průběhu příštího (u cyklůfor
awhile
začínajícího testem podmínky).
- return
- Vyhrazený příkaz
return
ukončí vykonávání právě prováděné funkce, a je-li mu předán výraz, pak jej vyčíslí a výslednou hodnotu vrátí jako návratovou hodnotu funkce.
string look_krovi()
{
if (mec && present(mec,this_object()) && mec->query_invis())
return wrap("Husté křoví... a v něm leží meč!");
return wrap("Naprosto nezajímavé křoví.");
}
Odkazy
Reference
- ↑ The History of Pike [online]. [cit. 2012-08-15]. Dostupné v archivu pořízeném dne 2010-02-04.
Literatura
- BARTLE, Richard. Designing Virtual Worlds. [s.l.]: New Riders, 2003. ISBN 0-13-101816-7. (anglicky)
- BUSEY, Andrew; POIRIER, Joseph. Secrets of the Mud Wizards. [s.l.]: Sams, 1995. Dostupné online. ISBN 0672307235. Kapitola 13. Essentials of LPC Programming (on LPMUDs). (anglicky)
Související články
Externí odkazy
- Výukový kurs Programování pro hračičky ve Wikiverzitě (založen na LPC)
- Descartes of Borg (George Reese). LPC Basics [online]. 1993 [cit. 2012-08-15]. Dostupné online. (anglicky)
- Descartes of Borg (George Reese). Intermediate LPC [online]. 1993 [cit. 2012-08-15]. Dostupné online. (anglicky)
- WIKH, Ronny. LPC [online]. 2003-07-07 [cit. 2012-08-15]. Dostupné online. (anglicky)
- Fórum uživatelů LPC a LPMudu (anglicky)
- Dokumentace k LPC a implementacím Amylaar LPMud a LDMud Archivováno 29. 12. 2015 na Wayback Machine. (anglicky)