Hlavní navigace

Knihovny řešící problém s unicode v Ruby

Jakub Šťastný

Již minule jsme si řekli, že problém s unicode není v Ruby nikterak neřešitelný. Z minula již umíme implementovat podporu unicode ve vlastní režii, dnes si ukážeme jak na to, abychom se pomyslnému objevování kola vyhnuli - povíme si o knihovnách, které tento problém řeší za nás.

Knihovna JCode

Knihovna JCode nám může s unicode pomoci ještě o trochu více než jen prostřednictvím hraní si s proměnnou $KCODE, jako tomu bylo minule. Není třeba pro ni chodit nijak daleko, je součástí standardní knihovny Ruby. Naleznete v ní několik šikovných metod, jako je each_char, která umí procházet řetězec po znacích, samozřejmě s ohledem na unicode, metodu jlength neboli jsize, která korektně určuje délku řetězce, a další. Dále předefinovává několik metod třídy String, aby fungovaly správně, zdaleka však ne všechny. Její problémy jsou v zásadě dva – jednak nepokrývá ani zdaleka všechny potřeby pro práci s unicode, k tomu ani není určena, a za druhé je na můj vkus až příliš neinvazivní. Osobně nevidím důvod, proč definovat jlength, když lze jednoduše předefinovat length.

Unicode

Knihovna Unicode je komplexním řešením potíží s unicode. Funguje v ní vše důležité včetně metod, jako je upcase, downcase a swapcase, což je pro češtinu a slovenštinu důležité. Interně využívá vyzrálou a spolehlivou knihovnu Iconv. Její jediný problém vidím, stejně jako v minulém příkladě, v přílišné neinvazivnosti, takže tato knihovna opět nepředefinovává metody třídy String, nýbrž si definuje třídy vlastní. Logicky tedy nezmění naše již existující skripty. Pracuje se s ní takto:

require "unicode"

puts Unicode::downcase("ČEŠTINA")
puts Unicode::upcase("čeština")

=> čeština
=> ČEŠTINA

Jediným „dodatkem“ této knihovny do třídy String je metoda to_u, která řetězec převede na jeho unicodovou variantu. Náš výše uvedený příklad tedy ještě lze zjednodušit na tento tvar:

require "unicode"

puts("čeština".to_u.upcase)

=> ČEŠTINA

Protože Unicode není součástí standardní knihovny, bude třeba ji nainstalovat ve vlastní režii. Je dostupná skrze balíčkovací systém RubyGems, takže by to neměl být žádný problém.

ActiveSupport::Mul­tibyte

Ruby on Rails jak známo unicode zvládají parádně. Podpora unicode v Rails je implementována pomocí knihovny ActiveSupport::Mul­tibyte. Vzhledem k velikosti a významu Rails si pochopitelně jeho vývojáři nemohou dovolit používat polovičatá řešení, což je ostatně vidět i na této knihovně. Dočkáte se zde komplexní podpory unicode, použití je podobné jako u výše zmíněné knihovny Unicode  – je třeba zavolat metodu převádějící klasický Ruby řetězec do řetězce unicodového. Metoda se tentokrát nejmenuje to_u, nýbrž chars. Použití je tedy snadné:

$KCODE="u"

puts("čeština".chars.upcase)
puts("čeština".chars[0..3])
puts("čeština".chars.reverse)

=> ČEŠTINA
=> češ
=> anitšeč

Jediná věc, na kterou je třeba dávat pozor, aby byla správně nastavena proměnná $KCODE  – bez jejího nastavení na u či UTF8 knihovna fungovat nebude! Pro podrobnější pohled do hlubin ActiveSupport::Mul­tibyte můžete shlédnout video o unicode v Rails nebo rovnou nahlédnout do API Ruby on Rails.

ICU4R

ICU4R je vazba Ruby na knihovnu ICU. To vypadá slibně, knihovna sama toho umí poměrně hodně, bohužel projekt je již delší dobu mrtvý. Stejně jako předchozí, i tato knihovna definuje vlastní třídu UString, do níž je třeba klasický řetězec převést. Více informací naleznete v ICU4R RDoc.

Další knihovny

Řada dalších knihoven si řeší podporu unicode pro svou interní potřebu po svém. Za všechny bych rád zmínil macovskou knihovnu RubyCocoa, která využívá API frameworku Cocoa nebo XML parser ReXML.

Závěr

Jak je vidět, knihoven podporující unicode je v Ruby spoustu. Nejužitečnější jsou patrně ActiveSupport::Mul­tibyte a Unicode. Ačkoliv zatím není podpora unicode přímo v Ruby samotném, díky těmto knihovnám si bez ní poměrně obstojně vystačíme. Zejména ActiveSupport::Mul­tibyte disponuje i dosti pokročilými možnostmi práce s unicode, které by dle mého názoru mohly postačit jakýmkoliv požadavkům na moderní podporu unicode.

Příště

V závěrečném díle našeho miniseriálku se podíváme na teoreticky nejlepší možný způsob řešení unicodové problematiky – využití přímé podpory unicode v jazyku. Protože podpora unicode v Ruby 1.8 de facto neexistuje, budeme se věnovat nadcházející verzi 1.9 a také JRuby, což je jedna z pokročilejších implementací Ruby v Javě.

Odkazy

Našli jste v článku chybu?