Linux E X P R E S

Facebook

Naučte se Ruby 10 - Bloky a Procs

ruby.jpg

Jedni to zatracují, jiní to obdivují, názory na následující techniku programování se liší. Ke které skupině programátorů se přikloníte vy, to už záleží jen na vás. Oč se jedná a jak se s tím pracuje, vám ukáže poslední díl seriálu, který je věnovaný programovacímu jazyku Ruby.


Stručně řečeno, Ruby umožňuje vzít blok zdrojového kódu (kódu mezi klíčovými slovy do a end), umístit ho do nějakého objektu (nazvaného Proc), uložit ho v proměnné nebo vložit do metody a spustit tento kus kódu kdekoliv chcete a především kolikrát chcete.

Podobá se to druhu určité metody s rozdílem, že není umístěna v objektu, ale sama o sobě je objektem, který můžete umístit snad kamkoliv.

pozdrav = Proc.new do
puts "Ahoj!"
end

pozdrav.call
pozdrav.call
pozdrav.call

zobrazí

Ahoj!
Ahoj!
Ahoj!

Blokům můžete předávat parametry stejně jako metodám.

mamRad = Proc.new do |dobrota|
puts 'Mam *rad* ' + dobrota + '!'
end

mamRad.call 'pivo'
mamRad.call 'vino'

zobrazí

Mam *rad* pivo!
Mam *rad* vino!

Zatím se to dost podobá metodám tak, je známe, takže pojďme zkusit něco jiného, vložme blok do nějaké metody.

Vkládání bloků do metod

def osloveni rec
puts 'Všichni se prosím ztište, chci vám říct něco důležitého'
rec.call
puts 'Tak to bylo vše, děkuji'
end

ahoj = Proc.new do
puts 'Dobrý den'
end

nashledanou = Proc.new do
puts 'Mějte se pěkně'
end

osloveni ahoj
puts
osloveni nashledanou

zobrazí

Všichni se prosím ztište, chci vám říct něco důležitého
Dobrý den
Tak to bylo vše, děkuji

Všichni se prosím ztište, chci vám říct něco důležitého
Mějte se pěkně
Tak to bylo vše, děkuji

V příkladu jsme vytvořili dva bloky ahoj a nashledanou. Vytvořené bloky se zavolají pomocí metody call.

Metody vracející Proc

Nyní budeme provádět následující "kouzla".

def vypocet proc1, proc2
Proc.new do |x|
proc2.call(proc1.call(x))
end
end

umocnit = Proc.new do |x|
x * x
end

secist = Proc.new do |x|
x + x
end

secistPakUmocnit = vypocet secist, umocnit
umocnitPakSecist = vypocet umocnit, secist

puts secistPakUmocnit.call(5)
puts umocnitPakSecist.call(5)

zobrazí

100
50

V příkladu jsme vytvořili blok umocnit a secist, dál metodu vypocet, které předáváme dva parametry (třídy Proc), a ty v této metodě spustíme jejich jménem tak, jak jsme zvyklí.

Pokud se vám nyní ježí vlasy hrůzou, je to normální. Buď si zvyknete, nebo Ruby zavrhnete. ;-)

Vytvoření bloku z metody

Následující příklad je trochu záludný, a tak si ho dobře promyslete.

class Array

def polozky &neco
jeSude = true

self.each do |objekt|
if jeSude
neco.call objekt
end

jeSude = (not jeSude)
end
end

end

['jablko', 'hruška', 'švestka', 'pomeranč'].polozky do |ovoce|
puts 'Takže vy máte rádi ' + ovoce
end

zobrazí

Takže vy máte rádi jablko
Takže vy máte rádi švestka

Program vybere z pole položky umístěné na místě 0, 2, 4, … v poli a vypíše je. Volání neco.call nás přenese do hlavního programu a provede vypsání textu na obrazovku. Všimněte si, že volaný text je vymezen direktivou do a end tak, jak jsme zvyklí. Takto vytvořený blok je nutno umístit na závěr všech parametrů metody a vždy mu předchází symbol &.

Pokud není výše popsaná technika jasná, podívejte se na další příklad a k tomuto se vraťte později.

def zpracovani popis, &blok
zacatek = Time.now

blok.call

trvani = Time.now - zacatek

puts popis + ': ' + trvani.to_s + 's.'
end

zpracovani '25 000 sčítání' do
cislo = 1

25000.times do
cislo = cislo + cislo
end

puts 'Číslo má ' + cislo.to_s.length.to_s + ' míst.'
end

zpracovani '1 000 000 sčítání' do
cislo = 1

1000000.times do
cislo = cislo + 1
end

puts 'Číslo má ' + cislo.to_s.length.to_s + ' míst.'
end

zobrazí např.

Číslo má 7526 míst.
25 000 sčítání: 0.221906s.
1 000 000 sčítání: 1.183532s.

Délku druhého čísla si raději nevypisujte, jinak byste mohli ztratit některé iluze o počítačích… Matematicky řečeno - vzniklé číslo je strašně moc dlouhé.

Vlastní příklad si myslím nepotřebuje další vysvětlení, nejen že se dobře čte, dobře i funguje a tak by měl správný program vypadat.

Platí to i opačně, co je složité přečíst, to je složité i napsat. ;-)

Příklady 10

  • Napište metodu, která vezme nějaký blok a zavolá ho každou hodinu, která dnes uplynula. Pro zjištění aktuální hodiny můžete použít funkci Time.now.hour.

A to je konec.

Seriál jsme pro vás připravili také v PDF pro tisk: Naučte se Ruby v PDF

Diskuze (2) Nahoru