Vlákno názorů k článku Parser bankovních výpisů aneb hrátky s Ragel od rawww - To si snad uz ze me vsichni dneska...

  • Článek je starý, nové názory již nelze přidávat.
  • 15. 2. 2008 1:02

    rawww (neregistrovaný)
    To si snad uz ze me vsichni dneska delate legraci. Nejenom ze jsem musel cekat kvuli nejake slavii nebo co to je 20 minut na autobus, ale jeste opet vidim cloveka, ktery je schopen psat kod "CESKY!". Tak toto uz je moc i na mne. Odesel mi stroj musim to v singleusermode pres mount -a s warningama scpeckovat vsechno na novy a tech 200GB od zakose me nebavi natolik abych neprudil. Jeste jednou se omlouvam za sve reci, ale toto mne bavi. ;o)

    eGo@easy.cz
  • 15. 2. 2008 9:01

    anonymní
    No mě zase baví takoví jako ty. Co je na tom probůh tak pohoršujícího? Je to čech, tak si pojmenovává proměnné česky. Já to tak dělám někdy taky.
  • 15. 2. 2008 9:02

    bez přezdívky
    Ano některé modernější programovací jazyky zvládnou jména proměnných i v UTF-8, takže by se dal kód by mohl být i "hezký a český". Osobně s tím nemám moc dobré zkušenosti. Ani si zrovna nejsem jistý, zda to umí zrovna Ruby :-)
  • 15. 2. 2008 10:56

    bez přezdívky
    Stejně mne od toho nakonec odradily technické problémy. Jednak používám různé textové editory a některé na začátek souboru vkládaly BOM. Pokud si dobře vzpomínám, tak Ruby v tom případě protestovalo (jiné jazyky obvykle také).

    Další problém byl, že ve standardní konzole Windows XP (cmd.exe) nešlo pořádně vypsat UTF-8. Nebo se mi to alespoň nepodařilo. Kódová stránka UTF-8 tam sice nastavit šla, ale při pokusu o výpis UTF-8 to spadlo. Ještě že command-line klient PostgreSQL (psql) umí výstup překódovat do CP1250 :-).

    Jinak UTF-8 v názvech proměnných čeká jistě velká budoucnost. Spočítejte si např., kolik toneru by ušetřila laserová tiskárna při výpisech zdrojáků, kdyby názvy proměnných byly např. čínsky - tedy jen jeden nebo dva znaky aniž by se ztratil význam daného jména. Počítám, že nejpozději do dvou let vznikne nějaká direktiva EU, která z ekologických důvodů bude délku názvu proměnných nějak omezovat. Pak nám ani nic jiného nezbyde :-)
  • 15. 2. 2008 11:53

    bez přezdívky
    Standardní konzole v XP jede v Unicode (UTF-16), jako vše ve Windows. Po nastavení code page na UTF-8 umí i UTF-8, a nepadá u toho (napadá mě, měl jste nainstalované konverzní tabulky pro UTF-8?). Ovšem není na UTF-8 stavěná, takže například vypisuje i BOM.
  • 15. 2. 2008 12:14

    bez přezdívky
    To nevím, jak je to s UTF-16, zas do toho ve Windows tak nevidím. Ale když si spustím cmd.exe, tak má (alespoň u mne) pro výstup nastavenou kódovou stránku 852 (tj. microsoftí starý "Latin 2") a vypisuje správně jen texty s tímto kodováním. Když tam nastavím TrueType font Lucida Console a přepnu si kódovou stránku na 1250, tak to bez problémů vypisuje texty s kódováním 1250. Když jsem tam zapnul kódovou stránku pro UTF-8 (tuším 65001), tak se to tvářilo v pořádku, ale když jsem tam spustil klienta s tímhletím kódováním, tak to spadlo na nějaký "Out of Memory" nebo co.

    Každopádně nechápu, nač jsou pro konzolu potřeba konverzní tabulky pro UTF-8, když běžné okenní programy si s UTF-8 rozumí bez problémů.
  • 15. 2. 2008 18:35

    bez přezdívky
    Vysvětlím. Windows řady NT pracují komplet v Unicode UTF-16. Znaky jsou vždy typu 16-bitového wchar_t, a nikdy 8-bitového char. Na konzoli se provádí výstup přes volání WriteConsoleW.

    Historické Windows 9x a 3x měly ovšem API v ANSI code page, s datovým typem char. Proto i Windows NT z důvodu zpětné kompatibility nabízejí volání pro 8-bit znaky typu char. Tato volání končí na A (WriteConsoleA). String se převede z kódové stránky do UTF-16, zavolá se wide verze volání, a poté se případně převede výsledek zpět na chary. V případě konzole máte možnost nastavit, z jaké kódové stránky se budou stringy převádět do Unicode (hint: kašlete na to, a jeďte v UTF-16, jak autoři zamýšleli). K tomu musí ale systém mít nainstalovanou konverzní tabulku. Shodou okolností existuje i tabulka pro UTF-8 (a v XP asi není by default nainstalovaná), jakkoliv NT konzole nikdy UTF-8 podporovat neměla.

    Dalším problémem jsou samozřejmě fonty. Pokud jede konzole v Unicode, ale font nemá Unicode znaky (ten defaultní je nemá), provede se konverze do code page fontu. Pokud nastavíte na konzoli font Lucida Unicode, bude zobrazovat ten subset Unicode, který Lucida Unicode nabízí (s japonštinou u tohoto fontu nepočítejte, azbuka tam je).

    Historicky je v SDK ještě možnost kompilovat Unicode či ANSI verzi aplikace. Typ TCHAR se mapuje by default na 8-bit char (použilo by se pro Win9x bez Microsoft Layer for Unicode). Pokud definujete symbol _UNICODE, mapuje se TCHAR na 16-bit wchar_t (cílem jsou Windows řady NT). Obdobně funkce tcslen() se mapuje na strlen() nebo wcslen().

    Vy jste zvyklý psát aplikace pro unixy. Na unixech je situace jiná. Glibc používá znaky typu char (wchar_t jen pro locale-enabled volání, kterých je pár kusů), a nikdo ani neví, jestli API zrovna krmíte UTF-8, 8859-2, 8859-5, nebo něčím jiným. To může vést třeba k tomu, že budete mít názvy souborů na disku pomíchané v UTF-8 a 8859-2. Každopádně pokud se snažíte psát aplikaci pro Windows tak, jak jste zvyklý jí psát pro unixy, budete asi používat znaky typu char, a tedy volat volání končící na A, určená pro Windows 9x. Unicode v takovém případě dostanate velmi těžko (nastavení code page je pro mnoho oblastí system-wide).

    Závěr: pokud píšete pro Windows, stringy jsou vždy tvořeny znaky typu wchar_t, a výstup na konzoli provádějte pomocí WriteConsole, nebo wprintf. Pokud trváte na typu char, vzdejte Unicode, nebo se připravte na problémy.

    Ještě reference:
    http://msdn2.microsoft.com/en-us/library/ms776442(VS.85).aspx --- Unicode in the Windows API
    http://msdn2.microsoft.com/en-us/library/2dax2h36.aspx --- MFC a Unicode
    http://msdn2.microsoft.com/en-us/library/c426s321.aspx --- Generic-Text Mappings in Tchar.h
    http://msdn2.microsoft.com/en-us/library/ms682010(VS.85).aspx --- Character-Mode Applications
    http://www.metagraphics.com/index.htm?page=pubs/mgct_language-portable-code.htm --- něčí souhrn
  • 19. 2. 2008 11:29

    segur (neregistrovaný)
    Pokud se na reprezentaci znaku používá 16bitová hodnota, tak to může býl leda UCS-2 (schopné reprezentavat prvních cca 65 tis. znaků Unicode), těžko UTF-16, které má variabilní délku 2 nebo 4 bajtů (a může tedy reprezentovat plný Unicode rozsah). Druhá možnost je, že jsem to pochopil špatně a Windows používá na uložení každého znaku buď jednu nebo dvě hodnoty wchar_t.
  • 19. 2. 2008 21:40

    bez přezdívky
    Původně UCS-2, tedy podpora 65k znaků. Pokud zapnete podporu surrogate pairs (by default je zapnutá například v asijských verzích) a máte vhodný IME, rázem je z toho UFT-16.
  • 19. 2. 2008 23:52

    Rejpal (neregistrovaný)

    Á, UTF-16, to je ta vyvážená kombinace paměťové úspornosti, endiánové nezávislosti a skvělé kompatibility s ASCII a C, které UTF-16 převzalo z UCS-4/UTF-32, a algoritmické jednoduchosti UTF-8? :o)

    V mailing listu IETF jsem zahlédl tenhle postřeh:

    "In a local file store, UTF-16 has some questionable advantages. Over the wire, it just decreases significantly the probability of interworking. The IETF and the UNIX operating system community had it just right when they chose to standardize on UTF-8 based interfaces."
    A to je, prosím, od lidí, co nám schvalují internetové standardy, jako je TCP/IP a podobně. Osobně myslím, že ideální stav je mít v paměti UCS-4 a na disku/na síti UTF-8.

    Ovšem i u toho UCS-4 v paměti bych ještě byl s hodnocením opatrný. Člověk s tím sice získá indexaci znaků (no, spíš "znaků", co do praktického významu) řetězce v konstantním čase (kterou s UTF-16 obecně rozhodně nemá), ale pořád ještě tu jsou i v UTF-32 kombinující sekvence, které hatí indexovaný přístup k "logickým" znakům tak jako tak. Jestli se nepletu, spousta precomposed znaků prostě neexistuje, a první komponovaný znak zabije konstantní časový přístup ke komponovanému grafému. Přitom kodér a dekodér UTF-8 je tak triviální, že nestojí skoro žádný strojový čas, rozhodně ne v porovnání s šířkou pásma paměti, disku a sítě. Takže je sporné, co je vlastně rychlejší.

    Dnešní doba díky hiearchii pamětí čím dál tím víc favorizuje kompaktní datové struktury, a v praxi je celá řada užitečných operací v UTF-8 pomalejší oproti UTF-32 v závislosti na velikosti reálných dat jen o tu konstantu, pokud není rovnou rychlejší kvůli kompaktnosti, a bůh ví, jak i poměrně normální operace typu délky řetězce ve znacích degenerují i na UTF-16/32. (Co třeba kanonická ekvivalence znaku U+216A a sekvence U+0058 U+0049? Nemusí to být jen diakritika...spousta zdánlivě stejných řetězců snadno může být "různě dlouhá", aplikací tradičního principu "spočítal jsem tu délku špatně, ale zato rychle". :o) U lineárního skenu ale může mít UTF-8 značnou výhodu, pokud je v něm daný text kompaktnější. To sice není zaručené, ale ve značné části světa to nakonec platí. A do přenosů dat na síti se aspoň nemotají ti odporní indiáni, což ocení každý technik. :-)))

  • 20. 2. 2008 9:19

    Lael Ophir (neregistrovaný)
    UTF-16 je kompatibilní s C. Navíc zpravidla uvažujeme UCS-2. UTF-16 se týká jen velmi omezené oblasti, a ani tam se ještě neprosazuje (japonci vzpomínají na MBCS, a hrozí se). UTF-8 má pár problémů. Vlastní kódování samozřejmě přináší jistá omezení, ale s implementací na unixech je to ještě horší. Pánové přemýšleli, jak za co nejméně peněz dostat Unicode do systému. Řešením je prostě cpát UTF-8 skrz API pracující s chary. Bohužel v systému mohou zároveň pracovat aplikace v historických code pages (třeba 8859-2, 8859-5) i UTF-8. A protože API ignoruje, odkud string přišel (s výjimkou locale-enabled volání, kterých je pět a půl), vzniká zmatek. Na disku se mísí názvy souborů v 8859-* s UTF-8; UTF-8 based aplikace ty názvy pak nemusí rozdýchat, protože jde o neplatné UTF-8 sekvence. Předpokládám, že podobné problémy má clipboard, a řada dalších věcí. A samozřejmě (g)libc implementuje řadu funkcí typu "najdi znak ve stringu", kde znak je char, takže funkce třeba s azbukou prostě nepůjde (ježto UTF-8 sekvence pro znak v azbuce je více charů). To se elegantně vyřešilo tak, že se u funkcí změnil popis, a nyní nehledají znaky, ale byte. Problém fakticky nevyřešen, ale dokumentace je formálně bezchybná :).

    Pěknou věcí je také rozeznávání, zda je soubor v Unicode, nebo ne. Unicode consorcium doporučuje používat Byte Order Mark. Jenže programy, které na UTF-8 nejsou stavěné, s BOM zápasí (shelly, PHP, Opera a další). Takže se na unixech BOM zásadně nepoužívá. Výsledkem je, že nikdo neví, co je v UTF-8, a co v národní code page. Ai na úrovni názvů souborů (viz výše), ani na úrovni obsahu textových souborů. Ve výsledku nelze rozeznat shell skript či konfigurák v UTF-8 od toho v 8859-*.

    Glibc exportuje pár funkcí i v UTF-32. Zajímavější ale je, že například Qt používá UTF-16. V rámci každého volání pak dochází k překladům na UTF-8 či UTF-32, a zase zpět na UTF-16. člověk neví, jestli se smát, křičet, nebo bušit hlavou o zeď.

    Když se na to podíváme, tak asi nelze než říci, že implementace Unicode na unixech se nějak nepovedla. Skoro by se chtělo říci, že starého psa novým kouskům nenaučíte.

    Operace nad stringy typu třídění, porovnávání apod. jsou vždy pomalé, pokud do věci zapletete locale. Bohužel, je to nutná daň za korektní podporu národních jazyků.
  • 15. 2. 2008 9:09

    Keny (neregistrovaný)
    A proč si asi myslíte že existuje lokalizace i pro angličtinu? Je moje věc co si do kódu napíšu - pokud to tak vyhovuje mě a lidem co na tom kódu pracují rovněž. Uživatele kódu to nemusí zajímat, pokud nad ním rovněž nemá v úmyslu bádat.
  • 15. 2. 2008 9:53

    anonymní
    myslim, ze je mozne ze spravne neodhadnete budoucnost sveho projektu...
    pokud jej zacnete psat cesky muze byt v hlubohe budoucnosti hodne tezke najit nejake zahranicni kolegy-spolupracovniky. ...treba...

    odstrasujicim prikladem budiz treba ten sql server od 602software. v te dobe kdyz jej zacali psat, bylo taky celkem v pohode mit v tom ceske texty...v te dobe bylo naprosto nezadouci posilat kod do sveta... a ted jsou v ... tezke pozici :)
  • 15. 2. 2008 10:18

    Keny (neregistrovaný)
    Zcela vás chápu. Je však rozdíl mezi větším projektem a drobnou, jednoúčelovou utilitkou jako v tomto příkladě. Měl jsem tedy alespoň pocit, že pisatel chtěl pouze demostrovat použití parseru Ragel.

    Pokud jde o komentáře, tak já jich využívám především k poznámkám, takže je pro mne důležité aby byly primárně srozumitelné pro mne. Tak proč se v nich pokoušet o eseje v angličtině.
  • 15. 2. 2008 10:20

    Keny (neregistrovaný)
    Ale o komentáře jako takové ani tak nejde jak tak koukám, spíš o názvy proměnných. Myslím že to je naprosto jedno. Pokud je kód přehledný a čitelný, tak na názvu proměnné nezáleží.
  • 15. 2. 2008 10:19

    Pepa (neregistrovaný)
    Ano, zbožňuji názvy jako protected string _ichWeissNichtWasIchHabHeuteGehabt;
  • 19. 2. 2008 16:06

    Rejpal (neregistrovaný)
    Připomněli jste mi můj oblíbený komentář na Slashdotu:

    Office worker: "why does Open Office take so long to load?"

    IT guy: "That's because the routines were written by a German guy in his free time. I'm sorry, little-miss-everybody-should-speak-English, but this poor guy was working for free. What do you expect?"

    Office worker: "what does the German language have to do with this?"

    IT guy: "Your PC was built in Austin, Texas. German is its second language. See this routine here, öffnenSiediegroßeAkte()? Your American PC doesn't know what that means, and has to consult a dictionary each time it sees it. There's a group of teenagers translating it into English. They work on one word each for greater safety. One of them saw two words of the program and spent several weeks in the hospital."

    :-D - doporučuju přečíst celé. ;-)