Ruby (programski jezik)

програмски језик

Rubi (engl. Ruby) je objektno orijentisani programski jezik. U sebi kombinuje sintaksu inspirisanu jezicima Perl i Ada, sa objektno orijentisanim osobinama nalik jeziku Smalltalk (Smalltalk), a deli i neke osobine sa jezicima Pajton, Lisp, Dylan i CLU. Rubi je jednoprolazni interpretirani jezik. Njegova glavna implementacija je slobodni softver pod licencom otvorenog koda.

Rubi (programski jezik)
Izgovara seRubi
Pojavio se1995. god.; pre 29 godina (1995)
Autor(i)Jukihiro Macumoto
Aktuelna verzija2.6.5
Datum aktuelne verzije1.10.2019.
Sistem tipovadinamički
ImplementacijeRuby MRI, YARV, JRuby, Rubinius, IronRuby, MacRuby, HotRuby
UticajiPerl, Pajton, Lisp, C++, Smalltalk, Dylan, CLU
Operativni sistemisvi značajniji
LicencaRubi Licenca
Veb-sajtwww.ruby-lang.org
DokumentacijaДокументација

Jukihiro „Mac“ Macumoto (Yukihiro Matsumoto) je sa razvojem ovog jezika počeo u februaru 1993. godine. Prvi put je objavljen 1995. godine, a trenutno je aktuelna stabilna verzija 1.9.3-p0 koja se može preuzeti sa zvanične strane jezika. Po mnogim programerima, Rubi slijedi princip „najmanjeg iznenađenja“, čime misle da je taj jezik oslobođen svih zamki i kontradiktornosti poznatih iz drugih jezika. Ime „rubi“ potiče od engleske riječi za „rubin“ (engl. Ruby) što je samo aluzija na „perl“ (engleski „biser").

Rubi je dugo vremena bio čisto japanska pojava, gdje je postigao veliku popularnost, otprilike jednaku kao Perl ili Pajton. Dokumentacija je postojala samo na japanskom. „Mac“ je tek krajem milenijuma krenuo sa aktivnostima popularizacije tog programskog jezika i izvan Japana. Veoma brzo je prihvaćen i ubrzo zatim su objavljeni mnogobrojni članci u stručnim časopisima kao i dokumentacija na drugim jezicima.

Rani koncepti uredi

“Razgovarao sam sa kolegom o mogućnostima objektno-orijentisanog skript jezika. Znao sam Perl, ali mi se nije stvarno sviđao, jer je bio nalik na toy jezike. Objektno-orijenstisani jezici su delovali vrlo obećavajuće. Tada sam naučio Python. Ali mi se nije sviđao, jer nisam mislio da je pravi objektno-orijentisani jezik: imao je samo neke karakteristike OO kao dodatke. Kao zaluđenik programskim jezicima i fan OO već 15 godina, zaista sam želeo istinski objektno orijentisan, jednostavan za upotrebu programski jezik. Tražio sam, ali nisam mogao pronaći jedan. Zato sam odlučio da ga napravim.”

Мацумото описује да је дизајн Рубија једноставан као језгро језика Lisp, са системом објеката налик на Smalltalk и практичне корисности као Perl.

Prvo izdanje uredi

Prvo javno izdanje programskog jezika Rubi[1] 0.95 objavljeno je na japanske newsgroup 21. decembra 1995. godine. Nakon toga, još tri verzije programskog jezika su objavljenje u dva dana. Nakon objavljivanja Rubi 0.95 , nekoliko stabilnih verzija jezika su objavljenje u narednim godinama:

  • Rubi 1.0 decembar 25, 1996
  • Rubi 1.2: decembar 1998
  • Rubi 1,4: avgust 1999
  • Rubi 1.6: septembar 2000
Godine 1997,  objavljen je prvi članak o jeziku Rubi na internetu. Iste godine, Matsumoto je angažovan od strane  netlab.jp da radi kao full-time developer u programskom jeziku Rubi.
Godine 1998. godine, pokrenuta je aplikacija Ruby Application Archive , zajedno sa jednostavnom stranicom na engleskom jeziku za Ruby. 
Godine 1999,  Macumoto i Keiju Ishitsuka su napisali prvu knjigu(The Object-Oriented Scripting Language Ruby, oktobar 1999.) o ovom programskom jeziku, za koji je poraslo interesovanje i van Japana, To je praćeno objavljivanjem još 20 knjiga o ovom jeziku u Japanu, rane 2000. godine.
Do 2000. godine, Ruby je postao popularniji nego Python u Japanu.  U septembru 2000. godine, prva knjiga na engleskom jeziku, Programming Ruby[2] je štampana, dok je nesto kasnije puštena u slobodnu prodaju, što je produbilo usvajanje ovog programskog jezika i u drugim zemljama. 

Najnovije verzije programskog jezika Rubi:

  • Rubi 2.5.0[3], oktobar 2017.
  • Rubi 2.4.2[4], septembar 2017.
  • Rubi 2.3.5[5], septembar 2017.

Filozofija programskog jezika Ruby[6] uredi

Macumoto je rekao da je Rubi dizajniran za produktivnost programera i zabavu, na načelima dobrog dizajna korisničkog interfejsa. Na Google Tech Talk-u, 2008. godine Macumoto dalje navodi: “Nadam se da će Ruby pomoći svakom programeru u svetu da bi bude produktivniji, i da uživa u programiranju, i da bude srećniji. To je primarna svrha jezika Rubi. “ On naglašava da dizajn sistema treba da pre zadovolji potrebe čoveka, a ne računara.

“Често људи, посебно програмери, фокусирају се на машине. Они мисле: “Радећи ово машина ће радити  брже, успешније...”  Они се фокусирају на машине. Али, у ствари, морамо да се фокусирамо на људе, на начин програмирања  или ради управљења апликацијама. Ми смо господари. Они су робови.”

Jezik Ruby treba da poštuje princip POLA, što znači da treba da se ponaša na takav način da minimizira zabune za iskusne korisnike. Macumoto je rekao da je njegov primarni cilj dizajna je bio da se napravi jezik koji on sam uživa koristi, smanjujući rad programera i moguću zabunu. On je rekao da nije primenio princip POLA u dizajnu jezika, ali je bez obzira na to fraza u bliskoj asocijaciji sa jezikom Ruby. Fraza je i sama bila izvor iznenađenja, posto su mnogi početni korisnici mogli da pomisle da jezik Rubi oponaša ponašanje drugih jezika. U maju 2005. godine diskusijom na newsgroup.comp.lang.ruby, Macumoto pokušao da distancira Rubi od POLA principa, objašnjavajući da pošto je bilo koji izbor dizajna iznenađujući za nekoga, on koristi lični standard u proceni iznenađenja. Ako smo dosledni u ličnom standardu, biće manje iznenađenja za upoznate sa standardom.

Macumoto je to objasnio na sledeći naćin: "Svi imaju sopstvenu pozadinu. Neki programiraju u Python-u, neki u Perl-y, I oni mogu biti iznenađeni različitim aspektima jezika. Onda oni dođu kod mene I kažu: “Bio sam iznenađen ovom karakteristikom jezika, tako da Rubi narušava princip najmanjeg iznenađenja”. Čekaj. Čekaj. Princip najmanjeg iznenađenja nije samo za tebe. Odnosi se na princip mog najmanjeg iznenađenja i odnosi se na princip najmanjeg iznenađenja nakon što naučiš Rubi veoma dobro. Na primer, ja sam bio C++ programer pre nego sto sam započeo dizajniranje jezika Rubi. Programirao sam isključivo u C++ dve ili tri godine. I posle dve godine C++ me I dalje iznenađuje."

Osobine uredi

  • Jednostavna i čitljiva sintaksa
  • „Čisto“ objektno orijentisani jezik (slično Smalltalku)
    • „Sve“ je objekt
    • Nasleđivanje od modula, umjesto višestrukog nasleđivanja
    • Unikatne metode (Singleton)
    • Dinamična promjena imena i nadogradnja klasa prilikom izvršenja programa
    • Iteratori
    • Prepisivanje operatora
    • Introspekcija (Reflection)
  • Netipizovane varijable
  • Obrada izuzetaka
  • automatsko oslobađanje nepotrebno zauzete memorije (garbage collection)
  • podrška Perlovih regularnih izraza (još nepotpuna)
  • podrška na više operativnih sistema
  • jedinstven interfejs za pristup bazama podataka
  • automatska dokumentacija (slično javadoc)
  • mogućnost i funkcionalnog i proceduralnog programiranja
  • liberalna licenca (GNU ili po želji)

Rubi je potpuno objektno orijentisan. Sve promenljive su objekti, što važi, za razliku od Džave (java), i za primitivne tipove.

Opšte karakteristike programskog jezika Rubi uredi

Rubi je interpretirani programski jezik, što znači da se izvorni kôd prevodi u kôd razumljiv računaru prilikom svakog izvršavanja programa. Očiti je nedostatak interpretiranih programskih jezika to da su sporiji nego kompajlirani programski jezici kao što je na primer C. Prednost je njihova veća fleksibilnost i kraće vreme izrade programa. Rubi je potpuno objektno- orijentisan programski jezik, što znači da se programski problemi rešavaju definisanjem klasa, a iz klasa nastaju pojedinačni objekti. Jedna je od prednosti objektno-orijentisanog pristupa to da on olakšava rad na velikim projektima jer je zadatak moguće podeliti na više programera, od kojih svaki može zasebno raditi na jednoj klasi ili na više njih. Na početku rada se definišu poruke koje se mogu slati određenom objektu, a nakon toga programeri imaju slobodu pisati i menjati kôd unutar klase pod uslovom da poruke ostaju nepromenjene. Objektno-orijentisana metoda rešavanja problema vrlo je efikasna jer raščlanjuje probleme na prirodan način sličan onome koji se upotrebljava u rešavanju problema u svakodnevnom životu.

Rubi pripada otvorenom kodu budući da je objavljen pod licencom GPL[7]. Vremenom je objavljeno više alternativnih interpretera programskog jezika Rubi. Najpoznatiji je JRuby[8] koji je napisan u programskom jeziku Java.

Prednosti i nedostaci uredi

Za Rubi se kaže da ima prirodnu sintaksu. Naime, sintaksa programskog jezika Rubi ne sadrži nepotrebne znakove i stoga kôd napisan u programskom jeziku Rubi ostavlja utisak jasnoće i jednostavnosti.

Primer jednostavnosti sintakse:

Pretpostavimo da želimo da pošaljemo poruku napuni_gorivo objektu moj_auto ukoliko rezervoar nije pun:

 moj_auto.napuni_gorivo unless moj_auto.spremnik_pun? 

Primetimo da je sintaksa jednostavna, bez suvišnih znakova u zapisu naredbe, za razliku od sintakse drugih programskih jezika.

Rubi-“programerov najbolji prijatelj” [9] uredi

Rubi je zamišljen kao programski jezik koji olakšava rad programeru lakoćom korišćenja, jednostavnošću i fleksibilnošću. Usmerenost na programera očita je u svim delovima programskog jezika. Najočitiji primer za to je mogućnost pisanja koda na više različitih načina. Evo nekoliko primera:

  puts “Hello,world” или puts(“Hello,world”)
  {“jedan”, “dva”, “tri”} 

Testovi uredi

Ispravljanje grešaka u kodu (eng. bug) vrlo je težak posao, naročito nakon što se završi razvoj i krajnjim korisnicima program preda na upotrebu. Najbolje je otkriti što veći broj grešaka prilikom same izrade programa.

Rubi omogućava pisanje testova koji testiraju izvorni kôd. To je nova programerska paradigma koja omogućava brži razvoj i samim tim manje troškove razvoja programa.Programeri koji pišu programe u programskom jeziku Rubi vrlo se često koriste testovima i oni su integralni dio svakog ozbiljnog proširenja ili programa.

Pokretanje programa uredi

Najjednostavniji je način pokretanja koda kreiranje datoteke s programskim kodom i pokretanje te datoteke naredbom ruby. Datoteke koje sadrže kôd napisan u programskom jeziku Rubi obično (po dogovoru) imaju ekstenziju .rb.

  ruby мој_програм.rb 

Osnove programskog jezika Rubi uredi

Promenljive uredi

Promenljiva je simboličko ime kojem je pridružena neka vrednost. Promenljiva je svojevrsno skladište (deo memorije računara) u kojem se nalazi neki podatak.

  >> moja_promenljiva = 7 

Tom je naredbom promenljivoj koja se zove moja_promenljiva pridružena vrednost 7. Ako se nakon toga u nekom izrazu upotrebi ime moja_promenljiva, interpreter će iz memorije računara uzeti vrednost promenljive moja_promenljiva (koja u tom slučaju iznosi 7) i uključiće je u izraz na mestu na kojem se spominje.

  >> puts moja_promenljiva * 2 
  14

Vrednost promenljive se može menjati. Pristup promenljivoj kojoj nije pridružena vrednost rezultira porukom o grešci.

Tipovi podataka uredi

Svaki podatak je određenog tipa. Osnovni tipovi podataka u programskom jeziku Rubi jesu brojevi, nizovi znakova (eng. string) i polja (eng. arrays).

Nizovi znakova(string) uredi

Nizovi znakova (eng. string) mogu se u programskom jeziku Rubi napisati na više načina. Najčešće se koriste dvostruki navodnici:

  >> "ovo je string"
  => "ovo je string" 

Dvostruki navodnici omogućavaju umetanje i izvršavanje izraza unutar samog stringa:

  >> "Ja imam #{100 + 100} dinara" 
  => "Ja imam 200 dinara"

Nizovi znakova mogu se napisati i koristeći jednostruke navodnike. U tom slučaju nije moguće u nizove znakova umetati i izvršavati izraze te upisivati posebne znakove:

  >> puts 'Ja imam #{100 + 100} dinara\ndrugi red'
  Ja imam #{100 + 100} dinara\ndrugi red

U programskom jeziku Rubi nil predstavlja nepostojeću ili nedefinisanu vrednost.

Hash-tablice (polja) uredi

Tip podataka pod nazivom polje (eng. hash) sličan je nizu, ali za ključeve možemo koristiti bilo koju vrednost. Niz ima svoj redosled, pa ako preskočimo indeks, stvaraju se vrednosti nil. Kod polja to nije slučaj budući da indeks može biti bilo koji tip podataka pa ne može biti reči o očekivanom redosledu indeksa.

Polje se definiše upotrebom vitičastih zagrada:

  >> a = {} 
  => {}

Vrednosti unutar polja dodaju se na isti način kao i kod nizova:

  >> a["kljuc"] = "Vrednost" 
  => "Vrednost"
  >> a 
  => {"kljuc"=>"Vrednost"} 

Polje možemo definisati i tako da mu odmah dodelimo vrednost:

  >> boja_kose = { 
     'ivan' => 'plava', 
     'marija' => 'crna', 
     'suzana' => 'plava'
  }

Karakteristika programskog jezika Rubi su i simboli: Simbol najčešće predstavlja neki objekat iz realnog sveta. Sličan je nizu znakova, ali zauzima manje memorije. Naziv simbola počinje dvotačkom i zatim se nastavlja kao niz znakova i brojeva.

  boja_kose= {
   :ivan => 'plava',
   :marija => 'crna',
   :suzana => 'plava', 
   :petar => 'crvena' 
  }

Kontrolne strukture i petlje uredi

IF uredi

Kontrolna struktura se može koristiti na više načina: Osnovni način:

  >> if (2 > 1) then 
  >> puts "istina"
  >> end 
  istina 
  => nil 

Svaka kontrolna struktura mora završiti izrazom end. Zagrade i ključna reč then nisu obavezni, a možemo sve napisati u jednom redu odvajajući izraze tačkom sa zarezom:

  >> if 2 > 1 ; puts "istina"; end 
  istina 
  => nil 

Ako imamo samo jednu naredbu koju želimo izvršiti u slučaju da je test istinit, možemo koristiti sledeći način pisanja:

  >> puts "istina" if 2 > 1 
  istina 
  => nil 

Kontrolnoj strukturi if možemo dodati ključnu reč else kao i u mnogim drugim programskim jezicima:

  >> if 5 > 10
  >> puts "istina" 
  >> else 
  >> puts "nije istina" 
  >> end 
  nije istina 
  => nil 

Rubi podržava i ključnu reč unless koja ima suprotan učinak od ključne reči if i namenjena je poboljšavanju izgleda i čitljivosti koda:

  >> puts "nije istina" unless 2 < 1 
  nije istina 
  => nil

WHILE/UNTIL uredi

Kontrolne strukture while i until koriste se slično kao u ostalim programskim jezicima:

  >> a = 0 
  => 0 
  >> while a < 5 
  >> puts a 
  >> a = a + 1 
  >> 
  end 
  0 
  1 
  2
  3 
  4 
  => nil 

Kontrolna struktura until radi obratno od kontrolne strukture while:

  >> a = 0 
  => 0 
  >> until a > 5 
  >> print a 
  >> a = a + 1 
  >> end 
  0 1 2 3 4 5 
  => nil

Sistemske naredbe uredi

Rubi omogućava izvršavanje sistemskih naredbi u ljusci operativnog sistema[10] na sledeći način:

  >> system "echo Ovo je sistemska naredba unutar ljuske" 
  Ovo je sistemska naredba unutar ljuske
  => true

Izlaz naredbe ispisuje se na ekran. Ako je naredba uspešno izvršena, tj. ako je povratni kôd jednak nuli, vraća se vrednost true. U svim ostalim slučajevima vraća se vrednost false. Ako želimo zapisati izlaz od sistemske naredbe u neku promenljivu, to možemo učiniti na sledeći način:

  >> a = `echo Ovo je naredba unutar ljuske`
  => "Ovo je naredba unutar ljuske\n" 
  >> puts a
  Ovo je naredba unutar ljuske 
  => nil 

Uspešnost izvršenja naredbe (izlazni kôd) možemo proveriti na sledeći način:

  >> $?.exitstatus
  => 0

Nula znači da je naredba uspešno izvršena, a svi ostali kodovi označavaju grešku.

Napomena: Imena konstanti u programskom jeziku Rubi se sastoje isključivo od velikih slova.

Višestruko pridruživanje vrednosti promenljivima uredi

Ponekad želimo dodeliti više različitih vrednosti u više različitih promenljivih. To činimo na sledeći način:

  >> a, b, c = 1, 2, 3
  => [1, 2, 3] 

Ukoliko na desnoj strani znaka za dodeljivanje postoji više vrednosti koje su odvojene zarezima, iz njih se stvara niz. Nakon toga članovi niza pridružuju se redom promenljivima na levoj strani. Proučimo što se događa ako na desnoj strani izraza ima više vrednosti nego što ima promenljivih na desnoj strani:

  >> a,b = 1,2,3 
  => [1, 2, 3] 
  >> a => 1 
  >> b => 2 

U ovom slučaju broj tri nije pridružen nijednoj promenljivoj. Proučimo šta se događa u suprotnom slučaju – ako je na levoj strani navedeno više promenljivih nego što ima vrednosti na desnoj strani:

  >> c = 100 
  => 100
  >> a, b, c = 1, 2 
  => [1, 2] 
  >> c 
  => nil

Budući da nije bilo dovoljno vrednosti na desnoj strani, promenljivoj c pridružena je vrednost nil (Null). Prethodna vrednost promenljive c (broj 100) nije sačuvana.

U programskom jeziku Rubi moguće je zameniti vrednosti promenljivih na jednostavniji nacin bez korišćenja dodatne, privremene promenljive:

a, b = b, a

Klase i metodi uredi

Klase su zaokružene celine koje se sastoje od koda koji je potreban za izvršavanje određenog zadatka. Definisanje klasa zapravo predstavlja definisanje koda. Klasu kreiramo koristeći ključnu reč class i nakon toga navođenjem imena klase. Ime klase mora početi velikim slovom. Nakon što smo naveli ime klase, definišemo sve metode koje klasa sadrži i na kraju dodamo ključnu reč end.

Metoda je deo koda koji izvršava određeni zadatak unutar klase. Metode su sastavni deo svake klase. Definisanje klase u stvari znači definisanje metoda. Kreiraćemo klasu Automobil koja se sastoji od metode svetla koja ispisuje "Uključujem svetla".

  >> class Automobil
  >> def svetla 
  >> puts "Uključujem svjetla" 
  >> end 
  >> end 

Postoje određena pravila pri imenovanju metoda. Imena metoda koje nešto proveravaju i vraćaju logičku vrednost najčešće završavaju upitnikom.

  >> niz = ["a","b","c"] 
  => ["a", "b", "c"] 
  >> niz.include?("a")
  => true 

U ovom primeru metoda include? proverava da li je neki objekat član niza ili nije. Imena metoda koje menjaju vrednost promenljivih nad kojima su pozvane najčešće završavaju uzvičnikom:

  >> a = "Srce"
  => "Srce" 
  >> a.upcase 
  => "SRCE"
  >> a => "Srce"
  >> a.upcase! 
  => "SRCE"
  >> a 
  => "SRCE"

U programskom jeziku Rubi moguće je definisati metode bez navođenja imena klase kojoj metoda pripada. Sledeći primer pokazuje takav slučaj:

  >> def moje_vrijeme 
  >> puts "Sada je #{Time.now}" 
  >> end 
  => nil

Pored metoda instance, koje se pozivaju nakon što smo kreirali objekat, postoji još jedna vrsta metoda koje se zovu metode klase ili statičke metode (eng. static method). Takve metode se definišu korišćenjem ključne reci self. Ispred imena. Primer:

  >> class Automobil 
  >> def self.boje 
  >> %w( crvena zelena bela plava crna ) 
  >> end 
  >> end

Tako definisanu metodu boje možemo isprobati na samoj klasi:

  >> Automobil.boje 
  => ["crvena", "zelena", "bijela", "plava", "crna"]

Definišimo dve metode pozdrav: jednu kao metodu klase, a drugu kao metodu instance. Neka klasa ima ime Kvadrat.

  >> class Kvadrat 
  >> def self.pozdrav 
  >> puts "Pozdrav od klase Kvadrat!" 
  >> end 
  >> def pozdrav 
  >> puts "Pozdrav od objekta klase Kvadrat!" 
  >> end 
  >> end

Pozovimo metodu klase:

  >> Kvadrat.pozdrav 
  Pozdrav od klase Kvadrat! 

Pozovimo metodu instance:

  >> Kvadrat.new.pozdrav 
  Pozdrav od objekta klase Kvadrat! 

U praksi se većina metoda definiše kao metode instance, a tek se u retkim slučajevima kreiraju metode klase. Na primer, lista mogućih boja univerzalna je za svaki automobil pa smo zato metodu boje kreirali unutar klase Automobil. Kao što postoje promenljive instance, tako u programskom jeziku Rubi postoje i promenljive klasa. Imena promenljivih klasa počinju s dva znaka @ (@@), za razliku od imena promenljivih instanci čija imena počinju s jednim znakom @. Doseg promenljivih klasa je cela klasa, za razliku od promenljivih instanci čiji je doseg objekat kojem pripadaju. Promenljive klasa su korisne ako želimo zabeležiti neki podatak koji se odnosi na celu klasu.

Objekti uredi

Objekat je konkretna implementacija ili realizacija neke klase. Kreiranje objekta:

  moj_auto=Automobil.new

Metode koje služe za kreiranje objekata određene klase zovu se konstruktori. Konstruktori se takođe mogu pozivati navodeći argument, čime nam omogućavaju da postavimo početne vrednosti svakom novom objektu koji kreiramo.

“Све је објекат”:

U programskom jeziku Rubi sve je objekat, uključujući i osnovne tipove podataka. Služeći se metodom class, možemo doznati kojoj klasi pripada neki objekat. Decimalni brojevi pripadaju klasi Float:

  >> 2.1.class 
  => Float 

Broj dva je objekat klase Fixnum:

  >> 2.class 
  => Fixnum

Čak je i nil objekt:

  >> nil.class 
  => NilClass 

Atributi i promenljive uredi

Svaki objekat koji kreiramo iz određene klase obično sadrži promenljive koje odražavaju njegovo stanje. Takve promenljive se zovu promenljive instance (eng. instance variables) i njihovo ime počinje znakom @. Dakle, iako možemo napraviti više objekata iz klase Automobil, svaki od tih objekata će imati svoje vlastite promenljive. Pretpostavimo da želimo zabeležiti neke karakteristike automobila kao što su proizvođač, model, godina proizvodnje, snaga motora, boja ili broj pređenih kilometara. Sve te karakteristike određenog konkretnog automobila zapisaćemo u promenljive instance. Promenljivima instance ne možemo pristupiti direktno već putem metoda. Primer:

  >> class Automobil 
  >> def postavi_boju(x)
  >> @boja = x 
  >> end 
  >> def ocitaj_boju 
  >> @boja 
  >> end 
  >> end

Programski jezik Rubi koristi pristupnike atributima radi jednostavnijeg I čitljivijeg koda. Primer:

  class Automobil 
  attr_accessor :proizvodjac, :model, :godina_proizvodnje, :snaga_motora, :prijedjeni_kilometri 
  end

Ključna reč attr_accessor klasi dodaje metode koje omogućavaju čitanje i pisanje u imenovane promenljive. Ispred imena promenljivih navodimo znak :

Sada možemo upotrebiti pristupnike i za druge promenljive:

  >> a.proizvodjac = "Zastava" 
  => "Zastava" 
  >> a.model = "Fićo" 
  => "Fićo" 
  >> a.godina_proizvodnje = 1971 
  => 1971 
  >> a.snaga_motora = 10 
  => 10 
  >> a.predjeni_kilometri = 0 
  => 0

Nasleđivanje uredi

Mnoge klase slične su jedna drugoj tako da nema potrebe definisati sve metode u svakoj klasi. Možemo prvo definisati generalnu klasu sa svim glavnim metodama. Nakon toga možemo kreirati specifične klase koje imaju još neke posebne funkcije. Na primer, ukoliko želimo definisati klasu Kabriolet možemo uzeti sve metode iz postojeće klase Automobil i dodati još neke posebne metode. Ako želimo da neka klasa nasledi sve metode iz neke druge klase, u prvi red definicije dodaćemo znak < iza imena klase koju definišemo i navesti ime klase od koje se nasleđuju metode. U sledećem primeru definisaćemo klasu Kabriolet koja nasleđuje sve metode klase Automobil i ima jednu dodatnu metodu za spuštanje krova:

  class Kabriolet < Automobil 
  def spusti_krov 
  puts "Spuštam krov!" 
  end 
  end 

Na ovaj način izbegavamo umnožavanje koda. Ako su dve klase slične, možemo kreirati zajedničke metode u zajedničkoj klasi i onda svaka od klasa može naslediti metode iz zajedničke klase i imati još neke dodatne.

Ulančavanje metoda uredi

Poput izraza i metode se u programskom jeziku Rubi mogu ulančavati. Pretpostavimo da niz znakova želimo ispisati velikim slova obrnutim redosledom. Jedan od načina je sledeći:

  >> a = "Ovo je string"
  => "Ovo je string" 
  >> a = a.upcase! 
  => "OVO JE STRING" 
  >> a = a.reverse! 
  => "GNIRTS EJ OVO" 
  >> puts a 
  GNIRTS EJ OVO 
  => nil 

Koristeći ulančavanje metoda isti rezultat možemo postići u samo jednom redu:

  >> puts "Ovo je string".upcase.reverse 
  GNIRTS EJ OVO 
  => nil

Blokovi i iteratori uredi

Blokovi i iteratori jedna su od specifičnosti programskog jezika Rubi. U drugim programskim jezicima postoje funkcije i procedure koje pozivamo jednim ili s više argumenata. Ti argumenti mogu biti brojevi, nizovi znakova i drugi tipovi podataka. Međutim, u programskom jeziku Rubi moguće je kao parametar zadati ne samo podatke već i sam programski kôd. Zaokruženi kôd koji možemo posmatrati kao celinu se zove blok. Definišimo jednostavnu metodu:

  >> def novi_blok 
  >> puts "Početak ponavljanja." 
  >> yield 
  >> yield 
  >> puts "Kraj ponavljanja." 
  >> end 
  => nil 

U gornjem smo primeru definisali metodu novi_blok. Posebnost je te metode da sadrži ključnu reč yield koja izvršava blok koji je poslat u pozivu te metode. Pozvaćemo metodu koju smo upravo definisali navodeći kao argument pri pozivanju te metode drugi programski kôd - blok. Taj se blok sastoji od samo jedne naredbe koja ispisuje "Pozdrav svima!":

  >> novi_blok{ puts "Pozdrav svima!" } 

  Početak ponavljanja.
  Pozdrav svima!
  Pozdrav svima!
  Kraj ponavljanja.

Dakle, blokovi se ne tretiraju na isti način kao drugi argumenti koji se prenose funkcijama. Argumenti koji nisu blokovi evaluiraju se pre poziva funkcije dok se blokovi evaluiraju tek prilikom poziva metode ѕield u telu funkcije. Blok može primati argumente svaki put kada ga izvršimo, pa se blokova koriste najčešće za implementaciju iteratora. Iterator je specijalna metoda koja izvršava blok na svakom članu niza. Na primer: a| puts a.upcase >> end

  ZGRADA 
  ULICA
  CESTA 
  => ["zgrada", "ulica", "cesta"] 

Prvo smo definisali niz koji se sastoji od tri člana. Svaki od tih članova je niz znakova. Nakon toga smo pozvali metodu koja je iterator koji redom za svaki član niza izvršava zadani blok predajući mu navedenog člana niza kao parametar. Isto smo mogli napisati i na kraći način, koristeći vitičaste zagrade umesto ključnih reči do i end: a| puts a.upcase }

Rad sa datotekama uredi

Datoteke se u programskom jeziku Rubi otvaraju na sledeći način: f = File.new("/etc/passwd","r") f.close

Datoteka je otvorena u modulu za čitanje i dodeljena promenljivoj f.

Naredbom f.close zatvorili smo datoteku.

Čitanje i pisanje uredi

Metod readline čita jednu liniju iz datoteke. Metod getc čita sledećih 8 bitova i pretvara ih u kod.

Metode lineno i pos služe za određivanje mesta na kome se nalazimo u datoteci (metod lineno određuje u kom se redu nalazimo, a metod pos karakter do koga smo stigli).

PRIMER:

file = File.new("/etc/passwd","r")
puts file.lineno
puts file.pos
file.readline
puts file.lineno
puts file.pos
puts file.getc
file.close

Ispis:

0
0
root:x:0:0:root:/root:/bin/bash
1
32
98

Za pisanje u datoteke mozemo koristiti metode: puts, print. Metod puts na kraj upisa dodaje oznaku za novi red, a metod print ne!

PRIMER:

 file = File.new("/tmp/moja_datoteka", "w")
 #<File:/tmp/moja_datoteka> 
 file.puts "Prvi red"
 file.close

Datoteke možemo odmah učitati kao niz karaktera, bez posebnog otvaranja, pomoću metoda read:

a = File.read("/etc/inittab")

Klasa File sadrži još mnoge metode koji se mogu izvršavati bez otvaranja datoteke.

Na primer možemo saznati ime direktorijuma u koje se nalazi datoteka, ime datoteke ili njenu veličinu:

 File.dirname("/tmp/moja_datoteka") 
 => "/tmp"
 File.basename("/tmp/moja_datoteka")
 => "moja_datoteka"
 File.size("/etc/passwd")
 => 2057

Rad sa direktorijumima uredi

Programski jezik Rubi sadrži i mnoge druge mogućnosti u radu sa direktorijumima i datotekama. Zato ga neki upotebljavaju kao zamenu za programiranje u ljusci operativnog sistema ( bash).

Ukoliko želimo da vidimo u kom direktorijumu se nalazimo, koristimo sledeću naredbu:

Dir.pw

Upravljanje imenima datoteka uredi

Datotekama možemo pristupiti i navodeći samo njihovo relativno ime (tj. relativnu putanju) uzimajući u obzir naš trenutni direktorijum.

U programskom jeziku Rubi postoji klasa Pathname, koja sadrži metode za upravljanje imenima datoteka.

Klasa Pathname je "spoljašnja" klasa pa je moramo učitati pre početka rada:

 require 'pathname'

Objekat klase Pathname kreiramo na sledeći način: (u ovom primeru koristimo realtivno ime datoteke uz pretpostavku da se trenutno nalazimo u direktorijumu /root):

  p = Pathname.new("Mail")

Klasa Pathname omogućava više od 70 operacija nad imenima datoteka i samim datotekama. Najznačajnije od njih su:

  p.realpath    #metod vraca puno ime datoteke (odnosno apsolutnu putanju)
  p.directory?    #vraca true ako je u pitanju direktorijum, u suprotnom false
  p.file?    #vraca true ako je u pitanju datoteka, u suprotnom false
  p.basename    #izdvaja ime datoteke
  p.dirname    #izdvaja ime direktorijuma u kojem se ta datoteka nalazi

Programski jezik Rubi poseduje specijalnu promenljivu koja sadrži ime datoteke sa kojom trenutno radimo. Ta promenljiva se zove __FILE__ i i omogućava nam pozivanje ostalih datoteka koje se nalaze u tom istom direktorijumu.

Naredba File.dirname(__File__) upućuje na direktorijum u kome se nalazi program koji smo pokrenuli.

Brisanje i kopiranje datoteka uredi

Metod delete koristimo za brisanje datoteke:

  File.delete("/tmp/moja_datoteka")

Proveru da li postoji datoteka vršimo pomoću metoda exist?:

  if File.exist?("/tmp/moja_datoteka")
      File.delete("/tmp/moja_datoteka")
  End

Za kopiranje datoteka služimo se metodom cp iz klase FileUtils:

  FileUtils.cp("/etc/inittab","/tmp")

  • Kao prvi argument navodi se ime datoteke koju želimo da iskopiramo
  • Kao drugi argument navodimo ime direktorijuma u koji želimo da smestimo kopiju
  • Nova datoteka će imati ime: /tmp/inittab

Ukoliko želimo da odjednom iskopiramo više datoteka, kao prvi argument navodi se niz:

  FileUtils.cp(["/etc/file1","/etc/file2"],"/tmp")

Klasa FileUtils podržava sve operacije nad datotekama uključujuci rekurzivno kopiranje, rekurzivno brisanje, kreiranje veza i drugo

Upravljanje greškama uredi

Klasa Exception uredi

Programski jezik Rubi omogućava pisanje programskog koda koji će se izvršiti u slučaju da program tokom izvršavanja naiđe na grešku.

Za upravljanje greškama služi klasa Exception.

Ukoliko sami ne odredimo šta će program raditi u slučaju da se dogodi neka programska greška, ispisaće se poruka sa opisom greške i prekinuće se izvršavanje programa.

Na primer, ako pokušamo promenljivoj čija je vrednost nil pristupiti kao da je niz:

a = nil
a[0]

Ispis:

 NoMethodError: undefined method `[]' for nil:NilClass

from (irb):2

Kôd za koji želimo da osiguramo poseban tretman u slučaju greške uvek počinje ključnom reči begin.

Sledeća je ključna reč rescue i ime klase ili potklase koja je nadležna za vrstu greške za koju želimo poseban tretman.

Ako želimo da poseban tretman vredi za bilo koju vrstu greške, navodimo klasu Exception (u suprotnom ćemo navesti neku od njenih 30-tak potklasa Nakon toga sledi kôd koji će se izvršiti ukoliko program naiđe na grešku.

Na prethodnom primeru:

begin
  a[0]
  rescue Exception
     puts "Doslo je do greske!"
end

Rezultat programa:

 Doslo je do greske!

U ovom smo primeru smo samo ispisali da je došlo do greške i nastavili dalje izvršavati kôd.

Ukoliko umesto ključne reci rescue upotrebimo ključnu rec raise, izvršiće se kôd koji sledi, ali nakon toga će se greška obrađivati na standardan predefinisan nacin.

U sledećem primeru koristimo ključnu reč raise. Ispisaće se poruka "Greška!" a nakon toga standardna poruka o grešci uz prekid izvršavanja programa: -{

begin
  0.upcase
  rescue Exception
  puts "Greska!"
  raise
end

Ispis

  Greska!
  NoMethodError: undefined method `upcase' for
  0:Fixnum
   from (irb):2
  Konverzija uspešna

Ukoliko želimo da se izvrši neki kôd bez obzira na to je li došlo do greške ili ne, koristimo ključnu reč ensure:

begin
  0.upcase
  rescue Exception
  puts "Greska!"
  ensure Exception
  puts "Zatvaram datoteke"
end

Ispis :

  Greska!
  Zatvaram datoteke

Gornji primer je primer uobičajene upotrebe ključne reči ensure (radi se o zatvaranju datoteka nezavisno od toga je li došlo do greške ili nije).

Da prilikom izvršavanja nije pokrenut neispravan kôd dešavalo bi se sledeće:

begin
  0.zero?
  rescue Exception
  puts "Greska!"
  ensure Exception
  puts "Zatvaram datoteke"
end

Ispis :

Zatvaram datoteke

S' obzirom na to da nije došlo do programske greške (naredba 0.zero? je ispravna), ne ispisuje se poruka Greška!, ali se izvršava deo koda u kojem piše Zatvaram datoteke.

Throw i catch uredi

Metodom catch definiše se programski blok koji se normalno izvršava do mesta poziva metode throw.

Kad interpreter naiđe na throw, prekida se izvršavanje odgovarajućeg programskog bloka.

Na primer: n| if not n throw :element_nil end sum += n p sum end end

Ako izvršimo ovaj programski kôd, on će rezultirati sledećim ispisom:

1
3
6

Ispis pokazuje da se petlja izvršila samo za prva tri člana niza. Kad je petlja naišla na četvrti clan niza cija je vrednost nil, što odgovara logičkoj vrednosti false, izvršio se metod throw i prekinulo se izvršavanje celog bloka.

Moduli uredi

Korišćenje više datoteka uredi

Programski kôd moguće je podeliti u više datoteka (file). Za uključivanje koda iz dodatnih datoteka koristimo require.

Na primer:

  require 'datoteka1'
  require 'datoteka2'

Takođe, interpreter neće prilikom pokretanja učitati sve klase koje su postoje u programskom jeziku Rubi nego samo osnovne. Stoga za uključivanje dodatnih klasa takođe moramo koristiti naredbu require.

Na primer, naredba require 'pathname' učitaće klasu Pathname i omogućiti njeno korišćenje.

Definisanje modula uredi

Modul je izolovani kôd koji se može koristiti u više aplikacija. Moduli omogućavaju grupisanje metoda, klasa i konstanti u jednu celinu.

Kreiraćemo modul koji sadrži funkciju za preračunavanje brzine zadate u metrima u sekundi u kilometre na sat:

 module Brzina
    def self.konverzija metara_u_sekundi
         metara_u_sekundi * 3.6
    end
 end

Sada možemo pozvati novu funkciju:

 Brzina.konverzija 10

Ispis:

36.0

Primeri uredi

Klasični „Pozdrav Svetu":

puts "Hello World!"

Reference uredi

Literatura uredi

Spoljašnje veze uredi