A Ruby programozási nyelv

Utasítások, vezérlési szerkezetek

1. Értékadás, üres utasítás

Az értékadásnak, mint kifejezésnek természetesen értéke is van, és ez a C-ben megszokott módon az értékül adott kifejezés értéke lesz. Tömbök is használhatóak az értékadás mindkét oldalán. Van üres utasítás: nil. A nyelv támogatja a szimultán értékadásokat is.

2. Szekvencia

A program kifejezésekből áll, tehát a kifejezések tekinthetőek utasításnak. Az utasításokat pontosvesszővel választjuk el egymástól, de egyértelmű esetekben az újsor karakter is megfelelő. Ha egy soron belül több kifejezés utasítást írunk, akkor ki kell tennünk a pontosvesszőt.

3. Elágazás

Az elágazások a következő szintaktikával írhatóak le:
if feltétel [then] # igaz ág end

Létezik a Perl-ből ismert módosító alak is:
kifejezés if feltétel

Természetesen else- és elsif-ága is lehet az if szerkezetnek. Az if-szerkezet teljes alakja:
if feltétel [then] # igaz ág [elsif [then] #... ] [elsif [then] #... ] [else # ... ] end

A then helyet használhatunk kettőspontot is, emellett használható a C-ből ismert <feltétel> ? <kifejezés1> : <kifejezés2> forma is. Az if kifejezésünk negálása helyett használhatjuk a más szkriptnyelvekből is ismert unless elágazást.

Lehet case-jellegű elágazást is használni. Ennek formája:
case kifejezés [when kif. [,kif. ...] [then] #... ] [when kif. [,kif. ...] [then] #... ] [else# ... end

A case szelektora egy közönséges Ruby-kifejezés. Mivel minden egyes ágon egy-egy kifejezést adhatunk meg, ezért a case használható a klasszikus értelemben véve egy adott kifejezés kiértékelésére, illetve egy egyszerűsített többágú if-ként is. A case szerkezetben megjelenő kifejezéseket a Ruby az === operátor segítségével értékeli ki, amely típus- és értékegyenlőséget vizsgál. Ennek megfelelően amennyiben saját osztályunkat egy case szerkezetben szeretnénk használni, elegendő az === operátor definiálnunk az adott osztályra. A case szerkezetben nincs átcsorgás a következő ágra. Az else-ág mindig az utoljára megnyitott if/case szerkezethez tartozik. Ez nem túl meglepő, hiszen mindkét szerkezetet end-del kell lezárni.

4. Ciklus

Természetesen van ciklus is a Rubyban. Legegyszerűbb típusa a következő:

4.times do puts "alma" end

Ez persze nem igazi ciklus, csak érdekességképpen mutattuk be. A hagyományos, elöltesztelős while-ciklus: while cond ... end Itt cond logikai kifejezés. Van előre nem ismert lépésszámú ciklus, például az előbb említett while ciklus. Hátultesztelős ciklus nincs, hasonló hatást azonban elérhetünk így:
i = 0 begin puts "i = #{i}" i += 1 end until i > 4

Eredmény:
i = 0 i = 1 i = 2 i = 3 i = 4

A ciklusfeltétel csak logikai típusú lehet. A nyelvben van for ciklus, ami azonban nem egészen olyan, mint mondjuk a C-beli.
for i in collection ... end

Itt a ciklusmag a collection minden elemére lefut egyszer. A collection lehet például egy egészeket tartalmazó intervallum, ez hasonlít leginkább a hagyományos for-ciklusra.
for i in (1..3) print i,"\n" end

A collection lehet sok minden más is, például egy tömb. Az előbb említettek miatt azt mondhatjuk, hogy a ciklusváltozó jellemzői közül csak az alsó és a felső határ állítható be és ezek is csak együtt. A ciklus megadásában szereplő collection belépéskor értékelődik ki. Végtelen ciklust írhatunk például így:
while (true) ... end

5. Vezérlésátadó utasítások

Cikluson belül használhatók a következő utasítások: next, break, redo. A next a C-s continue megfelelője, a break ugyanaz mint C-ben, a redo pedig az aktuális iterációt kezdi elölről. Az alábbi C kód e három utasítás jelentését demonstrálja:

while (condition) { label_redo: goto label_next; /* ruby: "next" */ goto label_break; /* ruby: "break" */ goto label_redo; /* ruby: "redo" */ ... ... label_next: } label_break: ...

A nyelvben megtalálható a catch és a throw utasítás is, ezek azonban a megszokottól eltérően nem a kivételkezelést, hanem a C-s goto utasítást és a labeleket valósítják meg. A catch utasítás segítségével elnevezhetünk egy blokk, majd a throw utasítás segítségével (scope-tól függetlenül) az immár névvel azonosított blokkhoz ugorhatunk. A throw-nak adható egy opcionális második paraméter, ami visszatérési értékként szolgál.

6. Blokkok

A Ruby blokkjai nem a változók lokalitását szolgálják, annál sokkal rugalmasabbak. Blokkokat {...} vagy do...end között adhatunk meg. A blokk elején || jelek között adhatunk meg változókat vesszővel elválasztva, melyeket majd mint paramétereket használhatunk fel a blokkon belül.

Blokkokat magukban is használhatunk, mint névtelen függvényeket. Ennek két módja van, a proc függvényt használva, vagy a lambda függvényt használva, mindkettő változóvá alakítja a blokkot. Két főbb különbség van:

Névtelen függvényeket a call függvénnyel tudunk meghívni, és paramétereket beleküldeni.

def proc_return proc { return "proc"}.call return "proc_return method finished" end def lambda_return lambda { return "lambda" }.call return "lambda_return method finished" end puts proc_return # proc puts lambda_return # lambda_return method finished

Blokkokat függvényekkel összhangban is használhatunk. Ehhez a függvényhívás után kell írni a blokkot, valamint a függvénynek tartalmaznia kell yield utasítás(ok)at, mellyel a blokkba küldhetünk értékeket a függvényen belülről.

def cubes(max) i=1 while i <= max yield i**3 i += 1 end end cubes(5) { |x| print x, ", "} # 1, 8, 27, 64, 125 sum = 0 cubes(5) { |x| sum += x} print sum # 225

Néhány hasznos blokkot alkalmazó függvény:

Ezeken kívűl még jóval több található a nyelvben. Általánosságban a listafüggvényekkel használható blokkok egy, a hash-ekkel használhatók pedig két paramétert várnak (kulcs,érték).