Portál AbcLinuxu, 1. května 2025 00:12

Ruby pro začátečníky - 4 (vstup, výstup)

11. 4. 2006 | Jaromír Hradílek
Články - Ruby pro začátečníky - 4 (vstup, výstup)  

Co se od našich programů obvykle očekává, je určitý způsob komunikace s uživatelem, ať už mluvíme o vypisování textu na terminál, nebo naopak o přijetí údajů z klávesnice.

Obsah

1. Výstup na obrazovku
  1.1 Příkaz puts
  1.2 Příkaz print
  1.3 Příkaz printf
2. Vstup z klávesnice
  2.1 Příkaz gets (readline)
  2.2 Metoda chomp
  2.3 Metoda to_i
  2.4 Metoda to_f

1. Výstup na obrazovku

Jak už je v Ruby zvykem, máme pro tyto účely hned několik možností, a to v podobě příkazů puts, print a printf. Pojďme se na ně podívat blíže.

1.1 Příkaz puts

Nejzákladnějším a taky asi nejobvyklejším příkazem k vypsání textu na obrazovku je puts, a pokud jste byli pozorní, několikrát jsem jej už použil v minulých dílech (3, 2, 1):

irb(main):001:0> puts "Ahoj, svete!"
Ahoj, svete!
=> nil
irb(main):002:0>

Jak vidíte, příkaz vypíše to, co je mu zadáno jako parametr, a odřádkuje. Jelikož se ve skutečnosti jedná o metodu (o metodách si budeme povídat zanedlouho a také zjistíme, že v Ruby jsou vlastně všechny příkazy metodami), lze jej zapsat i pro metody obvyklejším způsobem, tedy se závorkami:

irb(main):002:0> puts("Ahoj, svete!")
Ahoj, svete!
=> nil
irb(main):003:0>

Tento způsob zápisu se však v Ruby příliš nepoužívá.

Vypisovat lze hodnoty všech základních datových typů, kromě Hashe:

irb(main):003:0> puts "Ahoj"         # String
Ahoj
=> nil
irb(main):004:0> puts 256            # Fixnum
256
=> nil
irb(main):005:0> puts 1_079_252_848  # Bignum
1079252848
=> nil
irb(main):006:0> puts -7.25          # Float
-7.25
=> nil
irb(main):007:0> puts ['Prvni', 'Druhy', 'Treti']
Prvni
Druhy
Treti
=> nil
irb(main):008:0>

Pochopitelně lze vypisovat i výrazy a proměnné:

irb(main):008:0> PI = 3.14
=> 3.14
irb(main):009:0> puts PI
3.14
=> nil
irb(main):010:0> puts PI * 4**2
50.24
=> nil
irb(main):011:0> puts "Raz" + " a dva"
Raz a dva
=> nil
irb(main):012:0>

...a kupodivu i proměnnou typu Hash:

irb(main):012:0> udaje = {
irb(main):013:1*   "jmeno" => "Frantisek",
irb(main):014:1*   "prijmeni" => "Voprsalek"
irb(main):015:1> }
=> {"jmeno"=>"Frantisek", "prijmeni"=>"Voprsalek"}
irb(main):016:0> puts udaje
jmenoFrantisekprijmeniVoprsalek
=> nil
irb(main):017:0>

...jejíž výstup ovšem není příliš použitelný a jak vidno, chtělo by jej učesat.

Údajů můžeme k vypsání předat i více. Jako oddělovač poslouží čárka a každý se vypíše na nový řádek:

irb(main):017:0> puts "Prvni", "Druhy", "Treti"
Prvni
Druhy
Treti
=> nil
irb(main):018:0>

Vůbec nejobvyklejší (a taky nejpoužitelnější) je však kombinace výše uvedených možností:

irb(main):018:0> puts "Knock, knock, " + jmeno + "."*3
Knock, knock, Neo...
=> nil
irb(main):019:0>

1.2 Příkaz print

Příkaz print je svým použitím puts velmi podobný a ve skutečnosti se odlišuje jen tím, že po vypsání požadovaných údajů nepřejde sám od sebe na nový řádek:

irb(main):019:0> print "Kampak se nam zatoulal konec radku?"
Kampak se nam zatoulal konec radku?=> nil
irb(main):020:0>

Toto chování je neocenitelné v případě, že máme v plánu k textu později něco dopsat, ať už v cyklu, nebo na základě větvení programu (k tomu se také dostaneme). Odlišné je také chování při vypsání více údajů:

irb(main):020:0> print "Prvni", "Druhy", "Treti"
PrvniDruhyTreti=> nil
irb(main):021:0>

Na tomto místě by možná nebylo špatné ukázat si základní možnosti formátování textu, a to pomocí takzvaných escape sekvencí (tj. speciálních řídících znaků). Ty nám umožňují třeba vložit konec řádku ve kterékoli části řetězce, nebo použít tabulátor. Následující tabulka shrnuje ty nejběžnější:

sekvence: význam:
\\ zpětné lomítko \
\' apostrof '
\" uvozovky "
\b návrat o jeden znak
\n přesun na další řádek
\r přesun na začátek současného řádku
\t tabulátor

Použití některých z nich pak ilustruje následující příklad:

irb(main):021:0> print "Jmeno:\t\t", udaje["jmeno"], "\nprijmeni:\t", udaje["prijmeni"], "\n"
Jmeno:          Frantisek
prijmeni:       Voprsalek
=> nil
irb(main):022:0>

Jak vidíte, s vhodným použitím escape sekvencí můžeme dosáhnout mnohem přehlednějších a hezčích výstupů.

1.3 Příkaz printf

Escape sekvence jsou šikovná věc, nicméně můžeme se dostat do situace, kdy zjistíme, že nám prostě nestačí - třeba v případě, že budeme chtít zobrazovat údaje s přesností na určitý počet desetinných míst nebo je zarovnat na určitou stranu. Právě k těmto účelům je nám k dispozici příkaz printf, který možnosti formátování značně rozšiřuje. Použití je obdobné jako v jazyku C nebo Perl:

irb(main):022:0> printf "PI = %0.3f\n", 3.14159
PI = 3.142
=> nil
irb(main):023:0>

Co jsem to právě udělal? Prvním parametrem je řetězec obsahující zástupné symboly, na jejichž místo jsou pak dosazovány hodnoty v dalších parametrech. %0.3f je zmíněná zástupná značka a udává, v jakém formátu bude na její místo hodnota dosazena. Pojďme si ji nyní rozebrat znak po znaku:

Nejpoužívanější druhy konverze shrnuje následující tabulka:

znak: význam:
b převod do binární soustavy
c zadaná hodnota je převedena na příslušný znak dle tabulky ASCII
d celé číslo
e desetinné číslo v exponenciálním tvaru
E shodné s e, jen exponent je označován velkým znakem E
f reálné číslo
o převod do osmičkové soustavy
s řetězec
x převod do šestnáctkové soustavy
X shodné s x, jen velkými písmeny

Pojďmě si některé z nich ukázat:

irb(main):023:0> printf "%b", 42
101010=> nil
irb(main):024:0> printf "#97 => '%c'", 97
#97 => 'a'=> nil
irb(main):025:0> printf "%0.3e", 1_079_252_848
1.079e+09=> nil
irb(main):026:0> r=255;g=128;b=64
=> 64
irb(main):027:0> printf "rgb(%d,%d,%d) --> #%x%x%x", r, g, b, r, g, b
rgb(255,128,64) --> #ff8040=> nil
irb(main):028:0> printf "Hello, %s. How are you?", ENV["USER"]
Hello, blackened. How are you?=> nil
irb(main):029:0>
irb(main):016:0> printf "%7.2f\n%7.2f\n%7.2f\n", 3.14, 9.8, 20.645
   3.14
   9.80
  20.64
=> nil
irb(main):030:0>

Další často používanou vlastností je nechat vyplnit mezery zleva nulami:

irb(main):030:0> printf "%07.2f\n%07.2f\n%07.2f\n", 3.14, 9.8, 20.645
0003.14
0009.80
0020.64
=> nil
irb(main):031:0>

Možností formátování je pochopitelně mnohem víc, popisovat je všechny však přesahuje záběr tohoto seriálu. Neměl by však být problém si je dohledat v dokumentaci, velice dobře je tato problematika vysvětlena také v prvním dílu Učebnice jazyka C autora Pavla Herouta.

2. Vstup z klávesnice

2.1 Příkaz gets (readline)

Může se stát, že ve svém programu budete potřebovat za běhu přijmout údaje od uživatele. K tomuto účelu lze využít příkazu gets (eventuálně readline – jejich chování je totožné), který ze standardního vstupu přečte řetězec znaků, ukončený znakem konce řádku (tedy vše až do stisku klávesy Enter):

irb(main):031:0> jmeno = gets
Jaromir
=> "Jaromir\n"
irb(main):032:0> puts "Good evening, #{jmeno}."
Good evening, Jaromir
.
=> nil
irb(main):033:0>

Takto získaný vstup má však několik nedostatků – řetězec je uložen včetně znaku nového řádku (všimněte si tečky v příkladu), druhý nedostatek pak spočívá v tom, že uložená hodnota je vždy typu String bez ohledu na to, zadáme-li třeba číslo.

2.2 Metoda chomp

První nedostatek elegantně řeší metoda chomp, která z řetězce odstraní poslední znak, jedná-li se o znak konce řádku (v unixových systémech je to '\n', v Microsoft Windows pak '\r\n'):

irb(main):033:0> jmeno
=> "Jaromir\n"
irb(main):034:0> jmeno.chomp
=> "Jaromir"
irb(main):035:0> "Jaromir\r\n".chomp
=> "Jaromir"
irb(main):036:0>

Jak vidíme, v případě kombinace znaků '\r\n' dojde k odstranění obou. Tak je zaručena přenositelnot našeho programu na jinou platformu bez nutnosti dodatečných úprav zdrojového kódu. Tyto znaky však musí být přesně v tomto pořadí; při jejich prohození dojde k odstranění pouze posledního z nich:

irb(main):036:0> "Jaromir\n\r".chomp
=> "Jaromir\n"
irb(main):037:0>

Metodu chomp lze pochopitelně aplikovat přímo při čtení ze vstupu:

irb(main):036:0> jmeno = gets.chomp
Jaromir
=> "Jaromir"
irb(main):037:0>

Jen pro úplnost, existuje také příslušná alternativa s vykřičníkem, tedy chomp!

2.3 Metoda to_i

Říkal jsem, že příkazy gets a readline přijímají hodnotu typu String. Ale co když potřebujeme pracovat s číselnými hodnotami?

K převodu proměnné typu String na celočíselný typ (Fixnum, Bignum) slouží metoda to_i:

irb(main):037:0> "18".to_i
=> 18
irb(main):038:0> "18:40".to_i
=> 18
irb(main):039:0> "18 hodin 40 minut".to_i
=> 18
irb(main):040:0> "Je prave 18 hodin.".to_i
=> 0
irb(main):041:0> "-13.27".to_i
=> -13
irb(main):042:0>

Tato metoda hledá na začátku řetězce celočíselnou hodnotu. Pokud ji najde, vrátí příslušné číslo, přičemž jakékoli další znaky ignoruje. Nenajde-li ji, vrátí hodnotu 0. Čtení celočíselné hodnoty pak může vypadat třeba takto:

irb(main):042:0> n = gets.to_i
4
=> 4
irb(main):043:0> puts 2**n
16
=> nil
irb(main):044:0>

2.4 Metoda to_f

Stejně jako to_i pro celá, slouží metoda to_f k převodu řetězce na reálné číslo:

irb(main):044:0> "3.14159".to_f
=> 3.14159
irb(main):045:0> "2e-3".to_f
=> 0.002
irb(main):046:0> "37.6°C".to_f
=> 37.6
irb(main):047:0> "PI=3.14".to_f
=> 0.0
irb(main):048:0>

Čtení reálného čísla pak může vypadat třeba takto:

irb(main):048:0> polomer = gets.to_f
12.7
=> 12.7
irb(main):049:0> printf "prumer = %0.2f\n", polomer * 2
prumer = 25.40
=> nil
irb(main):050:0>

V příštím díle se podíváme na řídící struktury v Ruby.

Seriál Ruby pro začátečníky (dílů: 8)

První díl: Ruby pro začátečníky - 1, poslední díl: Ruby pro začátečníky - 8 (soubory, výjimky, kontakt s OS).
Předchozí díl: Ruby pro začátečníky - 3 (datové typy)
Následující díl: Ruby pro začátečníky - 5 (řídící struktury)

Související články

Ruby pro začátečníky - 1
Ruby pro začátečníky - 2 (komentáře, aritmetika, proměnné)
Ruby pro začátečníky - 3 (datové typy)
Seriál: BASH
Python a PyQt - 1 (úvod)
Python a PyQt - 2 (podmínky, cykly, tlačítka)
Začínáme programovat v jazyce Python
Kommander - 1 (Skriptované GUI)
Kommander - 2 (Starý parser)
Kommander - 3 (Nový parser)
Seriál: Začíname KProgramovať
Programujeme v PERLu - I
Programujeme v PERLu - II

Odkazy a zdroje

Ruby

Další články z této rubriky

LLVM a Clang – více než dobrá náhrada za GCC
Ze 4 s na 0,9 s – programovací jazyk Vala v praxi
Reverzujeme ovladače pro USB HID zařízení
Linux: systémové volání splice()
Programování v jazyce Vala - základní prvky jazyka

Diskuse k tomuto článku

11.4.2006 00:34 Kyosuke | skóre: 28 | blog: nalady_v_modre
Rozbalit Rozbalit vše Re: Ruby pro začátečníky - 4 (vstup, výstup)
Odpovědět | Sbalit | Link | Blokovat | Admin
Pokud jde o „učesání výstupu hashe“, co takhle šikovná metoda #p, která jakožto protokol vypisuje zpětně eval-ovatelnou hodnotu? :-)
irb(main):011:0> b = { :a => "prvni", :b => "druhy" }
=> {:b=>"druhy", :a=>"prvni"}
irb(main):012:0> p b
{:b=>"druhy", :a=>"prvni"}
=> nil
Jak moc jsou ábíčkáři inteligentní? ;-)
13.4.2006 11:05 MiG | Praha
Rozbalit Rozbalit vše Re: Ruby pro začátečníky - 4 (vstup, výstup)
Ještě učesanější, zvláště při vypisování vnořených hashů či objektů obecně, je vypsání serializovaného objektu ve formátu YAML.
irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> b = { 'a' => "prvni", 'b' => { 'b1' => 'vnoreny1', 'b2'=>'vnoreny2' } }
=> {"a"=>"prvni", "b"=>{"b1"=>"vnoreny1", "b2"=>"vnoreny2"}}
irb(main):003:0> str = b.to_yaml
=> "a: prvni\nb: \n  b1: vnoreny1\n  b2: vnoreny2\n"
irb(main):004:0> puts str
a: prvni
b:
  b1: vnoreny1
  b2: vnoreny2
=> nil
Metoda "y" se chová obdobně jako "p":
irb(main):005:0> y b
a: prvni
b:
  b1: vnoreny1
  b2: vnoreny2
=> nil
Deserializace se provede takto:
irb(main):006:0> b2 = YAML::load( str )
=> {"a"=>"prvni", "b"=>{"b1"=>"vnoreny1", "b2"=>"vnoreny2"}}
4.12.2007 11:47 Tomix
Rozbalit Rozbalit vše Re: Ruby pro začátečníky - 4 (vstup, výstup)
Odpovědět | Sbalit | Link | Blokovat | Admin
Jak je na tom Ruby s češtinou na výstupu?

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.