Symboly v Ruby
V předchozích dílech jsem občas symboly použil, ale nevysvětlil. Konstanty typu Symbol začínají dvojtečkou, např:
:toto_je_symbol
Dokumentace třídySymbol
říká, že je to reprezentace jmen a vnitřních řetězců interpretu jazyka Ruby. Pokud vás ale ani toto vysvětlení neuspokojilo, můžete symboly považovat za speciální druh řetězců, se kterými je povoleno provádět jen velmi omezený počet operací – vlastně jen porovnání na shodu a převod na „normální“ řetězec. Oproti normálním řetězcům je zde ale ještě jeden podstatný rozdíl. Pokud použijeme tutéž („normální“) řetězcovou konstantu několikrát, vždy se bude jednat i jinou instanci (jiný objekt). Naproti tomu tatáž konstanta typu Symbol je vždy i tatáž instance (tentýž objekt, jedináček) v kontextu celého interpretu jazyka Ruby.
Symboly se hojně používají například jako klíče v heších (viz například spouštění WEBricku). S velmi hojným použitím se setkáte i ve frameworku pro webové aplikace Ruby on Rails, o kterém si na Rootu přečtete v nejbližší době.
Co se v Ruby nepovedlo
Jako každý jazyk má Ruby své stránky světlejší i stinné. Ačkoliv, dle mého názoru, světlé stránky značně převažují, je vždy užitečné vědět i o těch stinných.
Unicode
Velkým zklamáním je zjištění, že Ruby verze 1.8.x nepodporuje žádné lokály, kódové stránky, Unicode – prostě nic takového. Vzhledem k tomu, že autorem Ruby je Japonec a že v Japonsku je Ruby velmi oblíbeným a rozšířeným jazykem, je absence Unicode téměř šokující. Metody jako řazení, převod znaků z malých na velké a zpět apod. fungují jen na písmena anglické abecedy. Prostě jen ASCII.
Autor slibuje podporu Unicode ve verzi 2.0, ale v současné verzi 1.9 (má to být jakési preview verze 2.0) jsem nic z Unicode zatím nenašel. Pokud některé knihovny Unicode potřebují (např. REXML pro zpracování XML), řeší si to většinou samy. Protože se Ruby nebrání mít v řetězcích cokoliv, lze používat např. i UTF-8 (to bylo ostatně použito i u většiny aplikací v minulých dílech). Dokonce pokud použijete při spuštění Ruby volby -Ku -rjcode
, budou vám pro kódování UTF-8 správně fungovat i některé metody třídy String pro (například size
/ length
).
Vlákna
Ruby nepoužívá nativní vlákna operačního systému. To má sice i výhodu, že na všech OS je v Ruby práce s vlákny stejná a lze paralelizovat program i v těch OS, kde nejsou vlákna vůbec podporována. Nicméně většina rozumných operačních systémů dnes vlákna nativně podporuje. Přístup použitý v Ruby však může zapříčinit, že např. déle trvající (blokující) vstupně/výstupní operace zablokuje všechna vlákna bez ohledu na to, zda mají s onou V/V operací něco společného. Pochybuji také, že vlákna v Ruby bez podpory nativních vláken mohou běžet skutečně paralelně na víceprocesorových systémech (ale nezkoušel jsem to a ani nijak důkladněji nezkoumal).
Lokální proměnné v bloku
Ruby má ne zcela logické chování, pokud se v bloku vyskytuje lokální proměnná. Mějme např. kód:
def funkce
a = 0
[1, 2, 3].each do |i|
a = i
b = i
end
...
end
Po vykonání kódu bude mít v místě tří teček proměnná a hodnotu 3, zatímco proměnná b nebude existovat. Pokud však lokální proměnná vznikne v jiných případech (například mezi while
a end
), existuje i nadále. To není zrovna konzistentní. Problémem může být i použití existující proměnné jako parametru cyklu (v našem případě i).
O dalších nepovedených věcech se můžete dočíst v zajímavé prezentaci „How Ruby Sucks“. A kdo že si to v ní dovolil to božské Ruby takhle pomluvit? Nikdo jiný než Yukihiro Matsumoto – ten, který Ruby vymyslel.
Závěr
Seriál o jazyku Ruby končí. Samozřejmě se nedalo pokrýt Ruby v celé šíři, ale to nebylo ani účelem. Ruby, stejně jako žádný jiný jazyk, nemůže být nástrojem na vyřešení každého problému. Ale na řešení mnoha problémů vhodné je. Doufám, že jsem alespoň trochu přispěl k tomu, aby se Ruby v takových případech bralo v úvahu jako možná alternativa Perlu, Pythonu, Javy nebo C#.