====== vystupy.pm ====== Modul umožňuje řídit výstupy z programu a podle potřeby je přesměrovávat nebo logovat do souborů, posílat mailem atd. Ti, kdo posílají data na výstup přes tento modul, se nemusejí starat, zda je soubor pro jejich druh výstupu již otevřen atd. Standardní použití: místo ''print()'' voláte funkci ''vystup()'', které předáte řetězec identifikující váš výstupní proud a řetězec, který se má vypsat. vystup("hlavni", "Tento text jde na výstup.\n"); Pokud modulu vystupy někdo dříve neřekl něco jiného, váš text poputuje na ''STDERR''. Typická věc, kterou asi budete chtít udělat, je zvolit jeden výstup, který má jít na ''STDOUT'' místo na ''STDERR''. Samozřejmě to stačí udělat jednou na začátku programu. V případě potřeby můžete na ''STDOUT'' přesměrovat i více výstupů najednou. use vystupy; $vystupy::vystupy{hlavni}{stdout} = 1; Zapnutí STDOUTu pro určitý výstup automaticky pro tento výstup vypne STDERR. Pokud byste chtěli posílat dotyčný výstup současně na STDOUT i STDERR, musíte to explicitně říct: use vystupy; $vystupy::vystupy{hlavni}{stdout} = 1; $vystupy::vystupy{hlavni}{stderr} = 1; Skutečné výhody použití modulu vystupy se projeví teprve, když chcete své výstupy logovat do souborů, abyste mohli později zjišťovat, proč program provedl to, co provedl. Modulu stačí říct cestu ke složce, kde se logy ukládají. Modul zajistí, aby logy z tohoto běhu programu nepřepsaly žádné starší logy. Každému souboru vyrobí jméno ve tvaru //n.x//, kde //n// je dosud nepoužité číslo (jednoznačně identifikuje běh programu v rámci této složky) a //x// je název výstupu. Logování půjde zapnout buď globálně pro všechny výstupy (něco jako $vystupy::log = 1) nebo jmenovitě pro jednotlivé výstupy ($vystupy::vystupy{hlavni}{log} = 1). Bude-li zapnuto globální logování, k nastavení logování u jednotlivých výstupů se nebude přihlížet. Tohle zatím není implementováno. Dosud se to dělalo tak, že v konfiguračním souboru se zapnul režim debug a všechny výstupy se logovaly. Další věci, které už jsou ve vystupy.pm nějak udělané, ale jejich implementaci by to chtělo dotáhnout, resp. zelegantnit: * míra ukecanosti a ladění (některé skupiny výstupů lze plošně vypnout, pokud uživatel nepožaduje ladící režim) * kódování jednotlivých výstupů (defaultně utf-8; další se přečte z konfiguráku, popř. nastavit jedno kódování pro všechny výstupy, které jdou přímo do terminálu, popř. se přímo dívat, zda jsme v dosu) * Některé výstupy chci pouze jako log, ale nechci je vidět na obrazovce (STDERR). Takže pokud je logování plošně vypnuté, tento výstup se úplně zahodí, pokud je zapnuté, tento výstup jde do logu. To není totéž, jako když je logování plošně vypnuté a nějaký soubor pošlu do logu natruc. Příklad: záznam konfigurace, s jakou byl běh spuštěn. * Posílání některých výstupů mailem (typicky závěrečný mail s výsledky testu; mail je současně upozorněním, že výpočet už doběhl). V budoucnosti bych mohl alternativně zařídit i upozornění na příkazovém řádku, jako jsem to měl v Marylandu. ====== Návrh řešení vstupů a výstupů v DZ Parseru ====== S výjimkou dočasných ladících výstupů na STDERR má monopol na výstup modul vystup. Všechny ostatní moduly volají jeho funkci vystup($nazev_vystupu). Výchozí nastavení má být takové, že funkce vystup() posílá nejvýše jeden druh výstupu (s jedním názvem) na STDOUT, všechny ostatní na STDERR. Veškerá další nastavení musí být v konfiguračním souboru. Napadají mě následující možnosti: - na stdout jde jiný než výchozí výstup - kopie stdoutu na stderr - kopie stdoutu nebo stderru do souboru - přesměrování některého výstupu pouze do souboru - výstupy do souboru pouze v případě, že je zadána / existuje pracovní složka - kopie některého výstupu do mailu (asi skládat všechny do jednoho mailu, který se pošle po skončení výstupu, u jiných variant mě zatím nenapadá využití) U train.pl jde na STDOUT výstup "stat" (soubor se statistikou, řádově desítky megabajtů). U parse.pl jde na STDOUT výstup "csts" (ostromečkovaný vstup). ----- Výchozí nastavení vstupu má být následující: - pokud po přečtení voleb z příkazového řádku zbyly nějaké argumenty, interpretují se jako cesty k souborům, jejichž obsah se má přečíst - pokud žádné argumenty nejsou / nezbyly, čte se standardní vstup U programů jako parse.pl jsou potřeba 2 vstupy (jednak soubor k rozebrání, jednak model). V tom případě je jeden vstup hlavní (zde soubor k rozebrání) a zachází se s ním způsobem uvedeným výše. Druhý (zde model) je vedlejší a musí být povinně uveden jako argument nějaké volby na příkazovém řádku (tedy ne jako samostatný argument, např. "model.stat", ale vždy pohromadě s volbou, např. "-s model.stat"). ----- Soubor s konfigurací je vlastně zvláštní druh vstupu. Nikdy by neměl být vyžadován jako povinný. Vždy by mělo být možné použít nejvýchozejší hodnoty zadrátované přímo ve zdrojáku (nejlépe u funkce, která umí číst konfigurační soubor), případně v proměnných prostředí. Pokud chceme použít soubor s konfigurací, předáme ho jako alternativní vstup, jak bylo uvedeno výše ("-ini konfig.ini"). Měli bychom odbourat dosavadní praxi, že se defaultně čte nějaký soubor "parser.ini", pokud se najde v aktuální složce - uživatel si pak hůř udrží přehled, co se vlastně děje. Pokud se konfigurační soubor použije, může předefinovat chování ostatních vstupů: pro každý vstup řekne cestu k souboru (nebo k více souborům pomocí zástupných znaků), které se mají na dotyčný vstup napojit. Lze použít i "-" pro STDIN, ale tím se trochu složitě vracíme k něčemu, co se dá udělat jednodušeji. ----- Jak tedy na výše nastíněný model přejít z toho, co mám teď? Ze všeho nejdřív asi musím odbourat konfigurační soubor. Z něj se mi pořád načítají cesty, odkud co číst a kam co psát.