Hlavní navigace

Ruby z rychlíku

Dalibor Šrámek

Ruby je mladý, (zatím) interpretovaný, objektově orientovaný programovací jazyk, vytvořený a nezávisle vyvíjený Yukihirem Matsumotem. Interpret jazyka je dobře přenositelný a momentálně existují verze pro různé varianty UNIXu, MS Windows, Mac OS, OS/2 a BeOS. Nejstručnější charakteristika praví, že Ruby=(Perl+Smalltalk)/2.

Základním zdrojem informací o Ruby je www.ruby-lang.org a vynikající on-line kniha Programming Ruby.

Kdy vás může Ruby zaujmout? Zejména pokud splňujete některou z následujících podmínek:

  • stále zkoušíte nové programovací jazyky
  • ještě nemáte svůj oblíbený skriptovací jazyk
  • hledáte v programování krásu konstrukce a potěšení z tvorby
  • máte rádi software s myšlenkou, jasným designem a absencí ad hoc konstrukcí

Článek předpokládá určitou zkušenost a orientaci v běžných pojmech procedurálního a objektového programování. Zabývat se budeme mimo jiné proměnnými, operátory, řídícími strukturami, I/O operacemi a ošetřováním výjimek.

Hello, World!

Přejděme tedy k praxi. Po instalaci můžete (za obvyklých podmínek) ihned spustit interpret v interaktivním režimu pomocí příkazu irb. Irb ihned vyhodnocuje každý zadaný řádek:

irb 0.6.1(99/09/16)
irb(main):001:0> 1+1
2
irb(main):002:0>

Dialog s irb ukončíte stiskem Ctrl+D.

Kód programu vytvořený libovolným editorem lze samozřejmě také uložit do souboru (obyčejně s příponou rb) a spustit příkazem ruby <soubor>.

Obligátní HelloWorld.rb by mohl vypadat například takto:

#!/usr/local/bin/ruby

# Nadefinujeme funkci bez parametrů. Definice končí příkazem end.
def helloWorld_1
  # Funkce puts vypisuje parametry na standardní výstup.
  puts 'Hello, world!'
end

# Zavoláme nadefinovanou funkci.
helloWorld_1

Asi nás nepřekvapí výsledek:

Hello, world!

Podívejme se, co lze zjistit pohledem na kód tohoto jednoduchého příkladu:

  • jak je u interpretovaného kódu zvykem, první řádek začínající na #! určuje cestu k interpretu
  • znak # zároveň označuje komentář, zbytek řádku je interpretem ignorován
  • při programování v Ruby nebudete dvě hodiny ladit kvůli chybějícímu středníku
  • pokud to nevede k nejednoznačnosti, nemusíte používat ani závorky
  • ačkoliv (jak uvidíme) je Ruby opravdu objektový jazyk, nevnucují se nám objekty za každou cenu – příkládek je čistě procedurální
  • kód se vykonává sekvenčně od začátku souboru a neexistuje žádný ekvivalent funkce main z jazyka C

Udělejme malinko složitější HelloWorld2.rb (možná ho plně pochopíte až po dočtení článku):

#!/usr/local/bin/ruby

# Podle toho, zda objekt zadaný parametrem reaguje
# na metodu 'times', funkce zobrazí n krát text, nebo
# přímo zadaný parametr.
def helloWorld_2(n)
  if n.respond_to?(:times)
    n.times { |x| puts "#{x}, Hello, world!" }
  else
    puts n
  end
end

helloWorld_2(3)
helloWorld_2('Konec')

Po spuštění získáme:

0, Hello, world!
1, Hello, world!
2, Hello, world!
Konec

Vidíme, že:

  • definice a volání funkce helloWorld jsou rozšířeny o použití parametru
  • ve funkci se používá řídící konstrukce if/else/end, která bude vysvětlena později
  • ve funkci se využívá volání metod zápisem objekt.metoda
  • volání respond_to? umožňuje zjistit, zda má objekt definovánu zadanou metodu
  • celá čísla mají definovánu metodu times, která volá zadaný blok tolikrát, jaká je hodnota čísla
  • aktuální hodnota iterované proměnné může být předávána do bloku
  • pro ohraničení řetězce lze použít apostrofy (jako v HelloWorld1) nebo uvozovky (jako v HelloWorld2)
  • obsah řetězce v apostrofech se již dále nezpracovává
  • obsah řetězce v uvozovkách se zpracovává (např. v řetězci #{výraz} se výraz vyhodnotí a celý řetězec se nahradí výsledkem)
  • navíc si řekneme, že obsah řetězce v obrácených apostrofech se nahradí standardním výstupem externího příkazu obsaženého v řetězci

a=33
puts '1: abc \n def #{a}'
puts "2: abc \n def #{a}"
puts `date`

Vypíše:

1: abc \n def #{a}
2: abc
 def 33
Fri Feb  1 09:58:58 CET 2002

Proměnné a operátory

Základní fakta:

  • proměnné není třeba deklarovat
  • není třeba se starat o typ proměnné – určuje si ho za běhu interpret (a je možné ho zjistit voláním metody type)
  • není třeba se starat o uvolňování paměti – obstará ho garbage collector
  • v tomto článku se setkáme pouze s lokálními proměnnými a globálními proměnnými – název lokální proměnné začíná malým písmenem, název globální velkým písmenem nebo znakem $

Čísla

Ruby podporuje celá i reálná čísla. Celá čísla odpovídající 32bitovému nebo 64bitovému integeru (podle platformy) jsou interně uložena jako obejkt třídy Fixnum. Větší celá čísla jsou ukládána jako objekt třídy Bignum. Bignum umožňuje pracovat s integery, jejichž velikost je omezena jen velikostí paměti počítače. Protože typy všech proměnných jsou v Ruby určovány až za běhu programu, je i přechod mezi dvěma integerovými typy bezbolestný:

n=8
7.times do                # blok pro opakování je uzavřen mezi 'do' a 'end'
  puts "#{n.type}  #{n}"  # metoda 'type' vrací typ proměnné
  n*=n
end

Vypíše:

Fixnum  8
Fixnum  64
Fixnum  4096
Fixnum  16777216
Bignum  281474976710656
Bignum  79228162514264337593543950336
Bignum  6277101735386680763835789423207666416102355444464034512896

Celá čísla je také možné zapisovat jako binární, oktalová nebo hexadecimální. Dekadické číslo 513 lze zapsat také jako:

  • binární 0b1000000001
  • oktalové 01001
  • hexadecimální 0×201

Protože jsou čísla objekty, ukažme si několik základních metod, které mají definovány:

puts -23.abs          # absolutní hodnota
puts 65.chr           # znak, jehož ASCII kód je roven číslu
puts 3.next           # o jedničku vyšší číslo
puts 0.zero?          # vrací 'true', když je číslo rovno nule
puts 10.remainder(3)  # zbytek po dělení čísla parametrem
puts 15.type          # typ proměnné

Jak jistě tušíte, výsledkem je:

23
A
4
true
1
Fixnum

Stojí za zmínku, že většina operátorů, o kterých bude řeč později, jsou ve skutečnosti metody s upravenou syntaxí volání: a+b můžeme napsat jako a+(b), což je volání metody ‚+‘ objektu ‚a‘ s parametrem ‚b‘.

Reálná čísla jsou uchovávána jako objekty třídy Float, a to ve dvojnásobné přesnosti. Float poskytuje několik základních metod:

puts 3.14.round   # zaokrouhlení podle matematických pravidel
puts 3.14.ceil    # nejbližší větší celé číslo
puts 3.14.floor   # nejbližší menší celé číslo
puts -3.14.round
puts -3.14.ceil
puts -3.14.floor

Nepřekvapí nás výsledek:

3
4
3
-3
-3
-4

Zbytek aritmetických operací je soustředěn v tzv. modulu Math a jejich vysvětlení přesahuje rozsah tohoto článku.

Řetězce

Řetězcové proměnné jsou v Ruby uchovávány v objektech třídy String. Jsou to v podstatě sekvence 8bitových znaků, takže v objektu String lze uchovávat i binární data (například načtená ze souboru). Obvykle se řetězce inicializují pomocí konstant uzavřených v uvozovkách nebo apostrofech a platí stejná pravidla pro vyhodnocování obsahu, jaká byla uvedena výše. Navíc nabízí Ruby pohodlnou cestu k inicializaci dlouhých, několikařádkových řetězců:

s1='Neinterpretuje\nse'
s2="Interpretuje\nse 1+1 = #{1+1}"
s3=<<KONEC
  Tento řetězec může mít několik řádků a končí
  až slovem, které je uvedeno za znaky '<<'.
  (Počítá se do něj i případné odsazení řádků.)
KONEC

puts s1
puts s2
puts s3

Výsledkem je:

Neinterpretuje\nse
Interpretuje
se 1+1 = 2
  Tento řetězec může mít několik řádků a končí
  až slovem, které je uvedeno za znaky '<<'.
  (Počítá se do něj i případné odsazení řádků.)

Protože práce s řetězci je programátorovým denním chlebem, poskytuje String opravdu velké množství metod pro manipulaci s nimi. Uveďme si jen několik jednoduchých příkladů:

puts 'HellO'.downcase         # převod do malých písmen
puts 'hello'.upcase           # převod do velkých písmen
puts 'hello'.length           # délka řetězce
puts 'hello'.include?('el')   # vrací 'true', pokud řetězec obsahuje parametr
puts 'hello'.index('el')      # pozice parametru v řetězci
puts 'hello'.reverse          # obrácený řetězec
puts 'hello'.reverse.reverse  # návratová hodnota je zase objekt, jehož
                              # metodu můžeme volat
puts '   hello   '.strip      # odstranění prázdných znaků ze začátku a konce
puts 'hello'.tr('he','Ha')    # zaměňuje znaky (jako příkaz 'tr' v UNIXu)

Získáme:

hello
HELLO
5
true
1
olleh
hello
hello
Hallo

Navíc můžeme počítat se silnými nástroji pro nahrazování a změny částí řetězců a pro práci s regulárním výrazy, o nichž bude ještě řeč.

Možná jste si již všimli konvence, kdy názvy metod vracejících hodnotu boolean končí otazníkem. Podobně exitují metody, jejichž název končí vykřičníkem. Vykřičník upozorňuje na to, že dochází přímo ke změně samotného objektu. (Normální metody vrací hodnotu, ale stav objektu zůstává nezměněn.)

a='hello'
puts a
puts a.reverse   # jen vrať hodnotu
puts a
puts a.reverse!  # vrať hodnotu a změň objekt
puts a

Vrací:

hello
olleh
hello
olleh
olleh

True, false, nil

Nebudeme-li se snažit o zbytečnou složitost, můžeme říct, že v Ruby jsou definovány tři speciální hodnoty, kterých také může proměnná nabýt:

  • true – označuje pravdu (např. pravdivý výsledek porovnání)
  • false – označuje nepravdu
  • nil – označuje prázdnou proměnnou (například nenalezený znak řetězce)

Použití osvětlí příklad:

puts 2<3               # to je pravda
puts 3<2               # to není pravda
puts 'abcd'.index 'r'  # znak v řetězci není - vrací se doslova "nic"

S výsledkem:

true
false
nil

Příště se podíváme na další datové typy a operátory, řídící struktury a také si povíme něco o tom, jak Ruby podporuje mocnou zbraň skriptovacích jazyků – regulární výrazy.

Našli jste v článku chybu?

19. 6. 2005 21:18

MaK (neregistrovaný)
Protože se pouštím do Ruby on Rails,
úvod do Ruby mi moc pomůže.
Díky za tento seriál a seriál Ruby a OOP.
Kdo začíná jako já, snad pomůže http://riters.com/RubyOnRails/


8. 2. 2002 17:57

Jakub Travnik aka jtra (neregistrovaný)

Neco existuje, ale nezkousel jsem to:
http://www.ruby-lang.org/en/raa-list.rhtml?name=MPI+Ruby

Kdyz hledate neco pro Ruby, musite se podivat do:
http://www.ruby-lang.org/en/raa.html





Vitalia.cz: 7 originálních adventních kalendářů pro mlsné

7 originálních adventních kalendářů pro mlsné

120na80.cz: Rovnátka, která nejsou vidět

Rovnátka, která nejsou vidět

Vitalia.cz: To nejhorší při horečce u dětí: Febrilní křeče

To nejhorší při horečce u dětí: Febrilní křeče

DigiZone.cz: R2B2 a Hybrid uzavřely partnerství

R2B2 a Hybrid uzavřely partnerství

DigiZone.cz: SES zajistí HD pro M7 Group

SES zajistí HD pro M7 Group

120na80.cz: Co všechno ovlivňuje ženskou plodnost?

Co všechno ovlivňuje ženskou plodnost?

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

120na80.cz: Horní cesty dýchací. Zkuste fytofarmaka

Horní cesty dýchací. Zkuste fytofarmaka

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Podnikatel.cz: Chtějte údaje k dani z nemovitostí do mailu

Chtějte údaje k dani z nemovitostí do mailu

Vitalia.cz: Nejlepší obranou při nachlazení je útok

Nejlepší obranou při nachlazení je útok

DigiZone.cz: V Plzni odstartovalo Radio 1

V Plzni odstartovalo Radio 1

Vitalia.cz: Potvrzeno: Pobyt v lese je skvělý na imunitu

Potvrzeno: Pobyt v lese je skvělý na imunitu

Podnikatel.cz: Vládu obejde, kvůli EET rovnou do sněmovny

Vládu obejde, kvůli EET rovnou do sněmovny

Měšec.cz: Za palivo zaplatíte mobilem (TEST)

Za palivo zaplatíte mobilem (TEST)

Lupa.cz: Obchod budoucnosti je bez front, košíků i pokladen

Obchod budoucnosti je bez front, košíků i pokladen

DigiZone.cz: Sat novinky: slovenská TV8 HD i ruský NTV Mir

Sat novinky: slovenská TV8 HD i ruský NTV Mir