# Acesta este un comentariu=begin
Acesta este un comentariu pe mai multe linii
Nimeni nu le foloseste
Si nici tu nu ar trebui sa o faci
=end# In primul rand: totul este un obiect# Numerele sunt obiecte3.class#=> Fixnum3.to_s#=> "3"# Aritmetica de baza1+1#=> 28-1#=> 710*2#=> 2035/5#=> 7# Aritmetica este doar "zahar sintactic"# pentru a putea chema metode pe un obiect1.+(3)#=> 410.*5#=> 50# Valorile speciale sunt obiectenil# Nimictrue# truefalse# falsenil.class#=> NilClasstrue.class#=> TrueClassfalse.class#=> FalseClass# Egalitate1==1#=> true2==1#=> false# Inegalitate1!=1#=> false2!=1#=> true!true#=> false!false#=> true# Excluzand "false", "nil" este singura valoare "falsa"!nil#=> true!false#=> true!0#=> false# Mai multe comparatii1<10#=> true1>10#=> false2<=2#=> true2>=2#=> true# Sirurule de caractere sunt obiecte'Sunt un sir de caractere'.class#=> String"Si eu sunt un sir de caractere".class#=> Stringfi_inlocuit="fi inlocuit""Pot #{fi_inlocuit} atunci cand folosesc dublu apostrof"#=> "Pot fi inlocuit atunci cand folosesc dublu apostrof"# Printeaza puts"Afisez rezultate!"# Variabilex=25#=> 25x#=> 25# Retineti faptul ca atribuire unei valori, o si returneaza pe aceasta# Asta inseamna ca poti sa faci atribuire multipla:x=y=10#=> 10x#=> 10y#=> 10# Prin conventie se foloseste "snake_case" in denumirea variabilelorsnake_case=true# Folositi nume descriptive pentru variablieadresa_radacina_proiect='/nume/bun/'adresa='/nume/nu atat de bun/'# Simbolurile (sunt obiecte)# Simbolurile sunt constante imutabile, reutilizabile, reprezentate intern # de o valoare numerica. Sunt deseori folosite in locul sirurilor de caractere # pentru a da un nume reprezentativ unei valori:exemplu_simbol.class#=> Symbolstatus=:exemplu_simbolstatus==:exemplu_simbol#=> adevaratstatus=='exemplu_simbol'#=> falsstatus==:aprobat#=> fals# Vectori# Acesta este un vectorvector=[1,2,3,4,5]#=> [1, 2, 3, 4, 5]# Vectorii pot contine diferite tipuri de date[1,"salut",false]#=> [1, "salut", false]# Vectorii pot fi indexati# de la inceputvector[0]#=> 1vector[12]#=> nil# Ca si aritmetica, accessul [valoare]# este doar "zahar sintactic"# pentru a chema metoda [] a unui obiectvector.[]0#=> 1vector.[]12#=> nil# De la sfarsitvector[-1]#=> 5# Cu un index de inceput si o lungimevector[2,3]#=> [3, 4, 5]# Sau cu un intervalvector[1..3]#=> [2, 3, 4]# Adauga elemente intr-un vector in felul urmator:vector<<6#=> [1, 2, 3, 4, 5, 6]# Hash-urile sunt dictionarele din Ruby cu perechi cheie/valoare.# Hash-urile sunt notate cu acoladehash={'culoare'=>'verde','numar'=>5}hash.keys#=> ['culoare', 'numar']# Poti lua valoare unui element dintr-un hash foarte rapid folosind cheiahash['culoare']#=> 'verde'hash['numar']#=> 5# Incercand sa accesezi un element dintr-un hash # printr-o cheie care nu exista va returna "nil".hash['nimic_aici']#=> nil# Incepand cu Ruby 1.9, este o sintaxa speciala # pentru atunci cand se folosesc simboluri drept chei:hash_nou={defcon:3,actiune:true}hash_now.keys#=> [:defcon, :actiune]# Pont: Atat vectorii (Array) si hash-urile (Hash) sunt enumerabile (Enumerable)# Ele impart o multime de metode utile precum each, map, count si altele# Structuri de controliftrue"instructiune if"elsiffalse"else if, optional"else"else, de asemenea optional"endfornumarin1..5puts"iteratia #{numar}"end#=> iteratia 1#=> iteratia 2#=> iteratia 3#=> iteratia 4#=> iteratia 5# TOTUSI, Nici una nu foloseste instructiunea for# In locul acesteia ar trebui sa folosesti metoda "each" si sa ii trimiti un block# Un bloc este o bucata de cod pe care o poti trimite unei metode precum "each".# Este analog pentru "lambda", functii anonime,# sau closures in alte limbaje de programare.## Metoda "each" a unui interval, ruleaza block-ul o data# pentru fiecare element din interval.# Block-ul primeste ca si parametru un index# Invocand metoda "each" cu un block, arata in urmatorul fel:(1..5).eachdo|index|puts"iteratia #{index}"end#=> iteratia 1#=> iteratia 2#=> iteratia 3#=> iteratia 4#=> iteratia 5# Poti de asemenea sa pui block-ul intre acolade(1..5).each{|index|puts"iteratia #{index}"}# Continutul unei structuri de date poate fi parcurs folosind "each".array.eachdo|element|puts"#{element} parte din vector"endhash.eachdo|cheie,valoare|puts"#{cheie} este #{valoare}"endindex=1whileindex<=5doputs"iteratia #{index}"index+=1end#=> iteratia 1#=> iteratia 2#=> iteratia 3#=> iteratia 4#=> iteratia 5nota='B'casenotawhen'A'puts"Bravo pustiule!"when'B'puts"Mai mult noroc data viitoare"when'C'puts"Poti mai mult"when'D'puts"Incet, incet..."when'F'puts"Ai esuat!"elseputs"Sistem de notare alternativ?!"end# Functiidefdublu(x)x*2end# Functille (si toate block-urile) # returneaza implicit valoarea ultimei instructiunidublu(2)#=> 4# Parantezele sunt optionale cand rezultatul nu este ambiguudublu3#=> 6dubludublu3#=> 12defsuma(x,y)x+yend# Argumentele metodei sunt separate printr-o virgulasuma3,4#=> 7sumasuma(3,4),5#=> 12# yield# Toate metodele au un parametru block, implicit si optional# care poate fi invocat folosit cuvantul cheie 'yield'defincercuiesteputs"{"yieldputs"}"endincercuieste{puts'Salut Mihai!'}# {# Salut Mihai!# }# Poti trimite un block unei functii.# "&" marcheaza o referinta trimisa unui blockdefvizitatori(&block)block.call"un_parametru"end# Poti trimite o lista de argumente, care va fi convertita intr-un vector (array).# Pentru asta se foloseste ("*")defvizitatori(*vector)vector.each{|vizitator|puts"#{vizitator}"}end# Defineste o clasa folosind cuvantul cheie "class"classOm# O variabila apartinand clasei. Este folosita in toate instantele clasei@@specie="H. sapiens"# Constructordefinitialize(nume,varsta=0)# Atribuie argumentul, variabilei "nume", care apartine doar unei instante@nume=nume# Daca varsta nu este data, o sa ii atribuim valoarea implicita# din lista de argumente (0, in cazul nostru)@varsta=varstaend# Metoda pentru a seta valoarea unei variabiledefnume=(nume)@nume=numeend# Metoda pentru a lua valoarea unei variabiledefnume@numeend# Functionalitatea de mai sus poate fi obtinuta # folosing metoda "attr_accessor" dupa cum urmeaza:attr_accessor:nume# Metodele pentru a lua si a seta valoarea unei variabile # pot fi de asemenea obtinute individial:attr_reader:numeattr_writer:nume# O metoda apartinand unei clase foloseste "self" pentru a se diferentia # de metodele unei instante ale clasei respective# Poate fi invocata doar pe clasa, si nu pe o instanta a acesteiadefself.spune(msg)puts"#{msg}"enddefspecie@@specieendend# Creaza o instanta a unei claseion=Om.new("Ionut Popescu")eugen=Om.new("Eugen Ionescu")# Sa invocam niste metodeion.specie#=> "H. sapiens"ion.nume#=> "Ionut Popescu"ion.nume="Ionut Popescu JR."#=> "Ionut Popescu JR."ion.nume#=> "Ionut Popescu JR."eugen.specie#=> "H. sapiens"eugen.nume#=> "Eugen Ionescu"# Invoca o metoda a unei claseOm.spune("Salut")#=> "Salut"# Scopul unei variabile este definit de modul in care le numim# Variabilele care incep cu $ au scop global$var="Sunt o variabila globala"defined?$var#=> "global-variable"# Variabilele care incep cu @ apartin unei instante@var="Sunt o variabila a unei instante"defined?@var#=> "instance-variable"# Variabilele care incep cu @@ apartin unei clase@@var="Sunt variabila unei clase"defined?@@var#=> "class variable"# Variabilele care incep cu litera mare sunt constanteVar="Sunt o constanta"defined?Var#=> "constant"# Clasele sunt de asemenea obiecte in ruby. Astfel incat clasele # pot avea variabile care apartin unei instante# O variabila care apartine unei clase poate fi accesata de toate # instantele acesteia si de clasele care o extind# clasa parinteclassOm@@foo=0defself.foo@@fooenddefself.foo=(valoare)@@foo=valoareendend# clasa copilclassMuncitor<OmendOm.foo# 0Muncitor.foo# 0Om.foo=2# 2Muncitor.foo# 2# Variabilele care apartin unei instante ale unei clase, # nu sunt impartite de (copii acesteia) clasele care o extindclassOm@bar=0defself.bar@barenddefself.bar=(valoare)@bar=valoareendendclassDoctor<OmendOm.bar# 0Doctor.bar# nilmoduleExempluModuldeffoo'foo'endend# Incluzand modulul instantei unui obiect# Extinzand modulul unei instante ale unei claseclassPersoanaincludeExempluModulendclassCarteextendExempluModulendPersoana.foo# => NoMethodError: undefined method `foo' for Persoana:ClassPersoana.new.foo# => 'foo'Carte.foo# => 'foo'Carte.new.foo# => NoMethodError: undefined method `foo'# Callbacks atunci cand includerea si extinderea unui modul sunt executatemoduleModulExempluCallBackdefself.included(base)base.extend(ClassMethods)base.send(:include,InstanceMethods)endmoduleClassMethodsdefbar'bar'endendmoduleInstanceMethodsdefqux'qux'endendendclassCevaRelevantincludeModulExempluCallBackendCevaRelevant.bar# => 'bar'CevaRelevant.qux# => NoMethodError: undefined method `qux'CevaRelevant.new.bar# => NoMethodError: undefined method `bar'CevaRelevant.new.qux# => 'qux'