Ahoj Jakube. Dneska bych ti rád vysvětlil datové typy. Cože co? Datové typy, přeci. Data, informace – jak říkalo Číslo 5. Už víš, že Ruby pracuje s nějakými proměnnými – tedy, že do proměnných ukládáme nějaká data. Ta data ale mají různé typy – máme tu čísla, řetězce, pole… A ještě dva speciální typy, a to symboly a konstanty.
V každém programu, který potom budeš psát, musíš přesně vědět, jaký datový typ ma daná proměnná. Ruby rozeznává tyto datové typy:
Fixnum – Číslo (celá čísla)
Celá čísla – integer (čti “intýdžr”) jsou taková, která neobsahují desetinnou čárku. Třeba -55, 0, 1, 2, 20, 35, 346976. Taková čísla – proměnné – můžeme sčítat, odečítat, prostě provádět s nimi matematické operace.
irb(main):010:0> 1999.class => Fixnum
a teď zkusíme nějakou operaci
irb(main):011:0> x = 100 => 100 irb(main):015:0> x=x+100 => 200 irb(main):016:0> x.class => Fixnum
Teď se podívej, jak vypadá dělení – 10/3 by mělo být 3 a nějaký zbytek.
irb(main):020:0> 10/3 => 3
Float – Číslo (reálná čísla)
Float – čti “flout”. Druhým typem čísel jsou reálná čísla – s desetinnou čárkou. Vypadají úplně stejně, akorát se zapisují včetně desetinné čárky, tedy, pardon – tečky.
irb(main):022:0> 1999.8.class => Float
irb(main):023:0> x = 100.5 => 100.5 irb(main):024:0> x = x + 1.8 => 102.3 irb(main):025:0> x.class => Float
a ještě si zkusíme to dělení, jako v případě Integer čísla.
irb(main):021:0> 10.0/3.0 => 3.33333333333333
Vidíš ten rozdíl? A to všechno jen kvůli jedné tečce navíc. Proto si dej ve svých programech vždy pozor, jak definuješ čísla a operace s nimi.
String – Řetězec
String (čti “string”) je asi nejjednodušší datový typ. To, že používáš string, řekneš v Ruby jednoduše. Stačí ho uzavřít do “uvozovek”.
irb(main):026:0> "Ahoj Kubo".class => String
Dej ovšem pozor, pokud chceš získat data – jako vstup od uživatele – a ty následně používat pro nějaké matematické operace. Vzpomeň si na dnešní den, kdy ti pořád nechodil tvůj program – a nakonec byla chyba právě v tutom. Proto u řetězců používáme několik metod na jejich převod – například na čísla.
irb(main):031:0> vstup = gets 20 => "20\n" irb(main):032:0> vstup.class => String
A budeme-li teď chtít proměnnou “vstup” vydělit nějakým číslem, stane se následující:
irb(main):033:0> vstup / 10 NoMethodError: undefined method `/' for "20\n":String from (irb):33 from :0
Použijeme tedy metodu pro převod na číslo – buď na celé číslo, a to “to_i” nebo na reálné – “to_f”
irb(main):034:0> vstup.to_i / 10 => 2
irb(main):035:0> vstup.to_f / 10.0 => 2.0
Stejně tak čísla můžeme převést zpět na řetězec, přes metodu “to_s”
irb(main):037:0> 10.to_s => "10"
Array – Pole
Pole (čti “e:rej”). Co je to pole? Zkus si pole představit jako vláček s vagónky. Vagónky můžeš přidávat i odebírat, můžeš zjišťovat jejich počet, vybírat osobní a nákladní… Pole fungují úplně stejně. Poli je jedno, jaké vagónky – objekty – obsahuje. Můžeš za sebe řadit čísla, řetězce, i další pole. Pole poznáš podle toho, že je uzavřené do hranatých závorek – “[]”
irb(main):038:0> vlacek = [10, 20, 30.3, "kuba", "masinka", 11.2] => [10, 20, 30.3, "kuba", "masinka", 11.2]
Zjistíš, kolik má pole prvků (vagónků)?
irb(main):043:0> vlacek.count => 6
a jak přidat další prvek do pole?
irb(main):044:0> vlacek.push "masinka" => [10, 20, 30.3, "kuba", "masinka", 11.2, "masinka"]
Hash – Asociativní pole
Hash (čti “heš”) je speciální typ pole. Tady každý prvek pole má i svůj klíč, podle kterého se dá opět najít. Představ si to jako schránky na dopisy, kde klíčem bude jméno osoby, a obsahem třeba počet dopisů. Hash se označuje složenými závorkami – “{}”
schranky = {"tata" => 0, "mama" => 2, "kuba" => 21} => {"kuba"=>21, "mama"=>2, "tata"=>0}
A teď použijeme klíč – zeptáme se, kolik dopisů má kuba ve schránce
irb(main):047:0> schranky["kuba"] => 21
Jak vidíš, funguje to. Klíč k asociativnímu poli – Hashi – se zapisuje do hranatých závorek, jako pole. Počet prvků zjistíš stejně jako u Pole
irb(main):048:0> schranky.count => 3
Symboly
Právě jsme si ukázali příklad s Hashem. Jako klíč do Hashe se dá použít i celé číslo (integer). Tak k čemu vlastně ty symboly? Symboly hlavně šetří paměť počítače. Představ si, že bys psal nějaký program, co bude fungovat jako adresář. Každý záznam bude jako Hash, a bude obsahovat jméno, příjmení a telefonní číslo. Abys mohl u každé položky definovat klíč, použiješ na to symbol. Symbol je vlastně řetězec, který ale není v uvozovkách, ale jen má na začátku dvojtečku. Také by neměl obsahovat mezeru a nějaké paznaky :)
irb(main):057:0> :ja_jsem_symbol => :ja_jsem_symbol irb(main):058:0> :ja_jsem_symbol.class => Symbol
A teď náš příklad s adresářem
irb(main):059:0> adresar = {:jmeno => "kuba", :cislo => "752323826"}
Právě jsme nadefinovali jeden záznam. A jak se teď dostat na jméno?
irb(main):061:0> adresar[:jmeno] => "kuba"
Pozorný čtenář jistě namítne – když napíšu “jmeno” => “kuba”, je to přeci to samé! Ano i ne. Použijeme-li totiž jako klíč k poli řetězec, Ruby toto “jmeno” uloží do paměti pokaždé jako nový objekt typu String, a tím si zabere další a další místo v paměti. U pár záznamů je to asi jedno, ale při stovkách, nebo tisících záznamů to již bude citelná ztráta paměti – a tím i rychlosti celého programu.
Symboly se také používají u metod, ale to si vysvětlíme až u metod samotných, beztak mám pocit, že máš plnou hlavu toho, co ses teď dozvěděl. Tak ještě poslední a končíme.
Konstanty
Pamatuješ, jak jsme spolu psali program na Sportku? Měli jsme tam dvě proměnné, kde jsme řekli, z kolika míčků se losuje a kolik se jich celkem vytáhne z osudí. Na to se přesně hodí konstanty. Konstanty jsou speciální druh. Jak je jednou nastavíš – tzn. přiřadíš jménu nějakou hodnotu, nejde to (bez chybové hlášky) už změnit. Vlastně – kontanty by se ani měnit neměly, prot to jsou konstanty :) Ukážu ti příklad z té Sportky.
irb(main):051:0> OSUDI = 49 => 49 irb(main):052:0> los = rand(OSUDI) => 32
Konstanty poznáš snadno. Jejich jmén je totiž zapsané velkými písmeny, nebo aspoň první písmeno je velké. Pokud se někde v kódu pokusíš změnit hodnotu konstanty, Ruby ti vynadá, ale hodnotu změní.
irb(main):053:0> OSUDI = 10 (irb):53: warning: already initialized constant OSUDI
Příště si probereme jednotlivé datové typy trošku detailněji. A půjdeme trošku hlouběji, ať to není jen takhle suchá teorie :)