2014-03-07 18:09:56 +00:00
|
|
|
---
|
|
|
|
contributors:
|
|
|
|
- ["David Underwood", "http://theflyingdeveloper.com"]
|
|
|
|
- ["Joel Walden", "http://joelwalden.net"]
|
|
|
|
- ["Luke Holder", "http://twitter.com/lukeholder"]
|
|
|
|
- ["Tristan Hume", "http://thume.ca/"]
|
|
|
|
- ["Nick LaMuro", "https://github.com/NickLaMuro"]
|
|
|
|
- ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
|
|
|
|
translators:
|
|
|
|
- ["Adrian Bordinc", "https://github.com/ellimist"]
|
|
|
|
filename: learnruby-ro.rb
|
|
|
|
---
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
# 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 obiecte
|
|
|
|
|
|
|
|
3.class #=> Fixnum
|
|
|
|
|
|
|
|
3.to_s #=> "3"
|
|
|
|
|
|
|
|
|
|
|
|
# Aritmetica de baza
|
|
|
|
1 + 1 #=> 2
|
|
|
|
8 - 1 #=> 7
|
|
|
|
10 * 2 #=> 20
|
|
|
|
35 / 5 #=> 7
|
|
|
|
|
|
|
|
# Aritmetica este doar "zahar sintactic"
|
|
|
|
# pentru a putea chema metode pe un obiect
|
|
|
|
1.+(3) #=> 4
|
|
|
|
10.* 5 #=> 50
|
|
|
|
|
|
|
|
# Valorile speciale sunt obiecte
|
|
|
|
nil # Nimic
|
|
|
|
true # true
|
|
|
|
false # false
|
|
|
|
|
|
|
|
nil.class #=> NilClass
|
|
|
|
true.class #=> TrueClass
|
|
|
|
false.class #=> FalseClass
|
|
|
|
|
|
|
|
# Egalitate
|
|
|
|
1 == 1 #=> true
|
|
|
|
2 == 1 #=> false
|
|
|
|
|
|
|
|
# Inegalitate
|
|
|
|
1 != 1 #=> false
|
|
|
|
2 != 1 #=> true
|
|
|
|
!true #=> false
|
|
|
|
!false #=> true
|
|
|
|
|
|
|
|
# Excluzand "false", "nil" este singura valoare "falsa"
|
|
|
|
|
|
|
|
!nil #=> true
|
|
|
|
!false #=> true
|
|
|
|
!0 #=> false
|
|
|
|
|
|
|
|
# Mai multe comparatii
|
|
|
|
1 < 10 #=> true
|
|
|
|
1 > 10 #=> false
|
|
|
|
2 <= 2 #=> true
|
|
|
|
2 >= 2 #=> true
|
|
|
|
|
|
|
|
# Sirurule de caractere sunt obiecte
|
|
|
|
|
|
|
|
'Sunt un sir de caractere'.class #=> String
|
|
|
|
"Si eu sunt un sir de caractere".class #=> String
|
|
|
|
|
2014-05-07 16:53:23 +00:00
|
|
|
fi_inlocuit = "fi inlocuit"
|
2014-03-07 18:09:56 +00:00
|
|
|
"Pot #{fi_inlocuit} atunci cand folosesc dublu apostrof"
|
2014-05-07 16:53:23 +00:00
|
|
|
#=> "Pot fi inlocuit atunci cand folosesc dublu apostrof"
|
2014-03-07 18:09:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
# Printeaza
|
|
|
|
puts "Afisez rezultate!"
|
|
|
|
|
|
|
|
# Variabile
|
|
|
|
x = 25 #=> 25
|
|
|
|
x #=> 25
|
|
|
|
|
|
|
|
# Retineti faptul ca atribuire unei valori, o si returneaza pe aceasta
|
|
|
|
# Asta inseamna ca poti sa faci atribuire multipla:
|
|
|
|
|
|
|
|
x = y = 10 #=> 10
|
|
|
|
x #=> 10
|
|
|
|
y #=> 10
|
|
|
|
|
|
|
|
# Prin conventie se foloseste "snake_case" in denumirea variabilelor
|
|
|
|
snake_case = true
|
|
|
|
|
|
|
|
# Folositi nume descriptive pentru variablie
|
|
|
|
adresa_radacina_proiect = '/nume/bun/'
|
|
|
|
adresa = '/nume/nu atat de bun/'
|
|
|
|
|
|
|
|
# Simbolurile (sunt obiecte)
|
|
|
|
# Simbolurile sunt constante imutabile, reutilizabile, reprezentate intern
|
2014-05-07 16:53:23 +00:00
|
|
|
# de o valoare numerica. Sunt deseori folosite in locul sirurilor de caractere
|
|
|
|
# pentru a da un nume reprezentativ unei valori
|
2014-03-07 18:09:56 +00:00
|
|
|
|
|
|
|
:exemplu_simbol.class #=> Symbol
|
|
|
|
|
|
|
|
status = :exemplu_simbol
|
|
|
|
|
|
|
|
status == :exemplu_simbol #=> adevarat
|
|
|
|
|
|
|
|
status == 'exemplu_simbol' #=> fals
|
|
|
|
|
|
|
|
status == :aprobat #=> fals
|
|
|
|
|
|
|
|
# Vectori
|
|
|
|
|
|
|
|
# Acesta este un vector
|
|
|
|
vector = [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 inceput
|
|
|
|
vector[0] #=> 1
|
|
|
|
vector[12] #=> nil
|
|
|
|
|
|
|
|
# Ca si aritmetica, accessul [valoare]
|
|
|
|
# este doar "zahar sintactic"
|
|
|
|
# pentru a chema metoda [] a unui obiect
|
|
|
|
vector.[] 0 #=> 1
|
|
|
|
vector.[] 12 #=> nil
|
|
|
|
|
|
|
|
# De la sfarsit
|
|
|
|
vector[-1] #=> 5
|
|
|
|
|
|
|
|
# Cu un index de inceput si o lungime
|
|
|
|
vector[2, 3] #=> [3, 4, 5]
|
|
|
|
|
|
|
|
# Sau cu un interval
|
|
|
|
vector[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 acolade
|
|
|
|
hash = {'culoare' => 'verde', 'numar' => 5}
|
|
|
|
|
|
|
|
hash.keys #=> ['culoare', 'numar']
|
|
|
|
|
|
|
|
# Poti lua valoare unui element dintr-un hash foarte rapid folosind cheia
|
|
|
|
hash['culoare'] #=> 'verde'
|
|
|
|
hash['numar'] #=> 5
|
|
|
|
|
2014-05-07 16:53:23 +00:00
|
|
|
# Incercand sa accesezi un element dintr-un hash
|
|
|
|
# printr-o cheie care nu exista va returna "nil".
|
2014-03-07 18:09:56 +00:00
|
|
|
hash['nimic_aici'] #=> nil
|
|
|
|
|
2014-05-07 16:53:23 +00:00
|
|
|
# Incepand cu Ruby 1.9, este o sintaxa speciala
|
|
|
|
# pentru atunci cand se folosesc simboluri drept chei:
|
2014-03-07 18:09:56 +00:00
|
|
|
|
|
|
|
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 control
|
|
|
|
|
|
|
|
if true
|
|
|
|
"instructiune if"
|
|
|
|
elsif false
|
|
|
|
"else if, optional"
|
|
|
|
else
|
|
|
|
"else, de asemenea optional"
|
|
|
|
end
|
|
|
|
|
|
|
|
for numar in 1..5
|
|
|
|
puts "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".
|
2014-05-07 16:53:23 +00:00
|
|
|
# Este analog pentru "lambda", functii anonime,
|
|
|
|
# sau closures in alte limbaje de programare.
|
2014-03-07 18:09:56 +00:00
|
|
|
#
|
2014-05-07 16:53:23 +00:00
|
|
|
# Metoda "each" a unui interval, ruleaza block-ul o data
|
|
|
|
# pentru fiecare element din interval.
|
2014-03-07 18:09:56 +00:00
|
|
|
# Block-ul primeste ca si parametru un index
|
|
|
|
# Invocand metoda "each" cu un block, arata in urmatorul fel:
|
|
|
|
|
|
|
|
(1..5).each do |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.each do |element|
|
|
|
|
puts "#{element} parte din vector"
|
|
|
|
end
|
|
|
|
hash.each do |cheie, valoare|
|
|
|
|
puts "#{cheie} este #{valoare}"
|
|
|
|
end
|
|
|
|
|
|
|
|
index = 1
|
|
|
|
while index <= 5 do
|
|
|
|
puts "iteratia #{index}"
|
|
|
|
index += 1
|
|
|
|
end
|
|
|
|
#=> iteratia 1
|
|
|
|
#=> iteratia 2
|
|
|
|
#=> iteratia 3
|
|
|
|
#=> iteratia 4
|
|
|
|
#=> iteratia 5
|
|
|
|
|
|
|
|
nota = 'B'
|
|
|
|
|
|
|
|
case nota
|
|
|
|
when '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!"
|
|
|
|
else
|
|
|
|
puts "Sistem de notare alternativ?!"
|
|
|
|
end
|
|
|
|
|
|
|
|
# Functii
|
|
|
|
|
|
|
|
def dublu(x)
|
|
|
|
x * 2
|
|
|
|
end
|
|
|
|
|
2014-05-07 16:53:23 +00:00
|
|
|
# Functille (si toate block-urile)
|
|
|
|
# returneaza implicit valoarea ultimei instructiuni
|
2014-03-07 18:09:56 +00:00
|
|
|
dublu(2) #=> 4
|
|
|
|
|
|
|
|
# Parantezele sunt optionale cand rezultatul nu este ambiguu
|
|
|
|
dublu 3 #=> 6
|
|
|
|
|
|
|
|
dublu dublu 3 #=> 12
|
|
|
|
|
|
|
|
def suma(x,y)
|
|
|
|
x + y
|
|
|
|
end
|
|
|
|
|
|
|
|
# Argumentele metodei sunt separate printr-o virgula
|
|
|
|
suma 3, 4 #=> 7
|
|
|
|
|
|
|
|
suma suma(3,4), 5 #=> 12
|
|
|
|
|
|
|
|
# yield
|
|
|
|
# Toate metodele au un parametru block, implicit si optional
|
|
|
|
# care poate fi invocat folosit cuvantul cheie 'yield'
|
|
|
|
|
|
|
|
def incercuieste
|
|
|
|
puts "{"
|
|
|
|
yield
|
|
|
|
puts "}"
|
|
|
|
end
|
|
|
|
|
|
|
|
incercuieste { puts 'Salut Mihai!' }
|
|
|
|
|
|
|
|
# {
|
|
|
|
# Salut Mihai!
|
|
|
|
# }
|
|
|
|
|
|
|
|
|
|
|
|
# Poti trimite un block unei functii.
|
|
|
|
# "&" marcheaza o referinta trimisa unui block
|
|
|
|
def vizitatori(&block)
|
|
|
|
block.call "un_parametru"
|
|
|
|
end
|
|
|
|
|
|
|
|
# Poti trimite o lista de argumente, care va fi convertita intr-un vector (array).
|
|
|
|
# Pentru asta se foloseste ("*")
|
|
|
|
def vizitatori(*vector)
|
|
|
|
vector.each { |vizitator| puts "#{vizitator}" }
|
|
|
|
end
|
|
|
|
|
|
|
|
# Defineste o clasa folosind cuvantul cheie "class"
|
|
|
|
class Om
|
|
|
|
|
|
|
|
# O variabila apartinand clasei. Este folosita in toate instantele clasei
|
|
|
|
@@specie = "H. sapiens"
|
|
|
|
|
|
|
|
# Constructor
|
|
|
|
def initialize(nume, varsta=0)
|
|
|
|
# Atribuie argumentul, variabilei "nume", care apartine doar unei instante
|
|
|
|
@nume = nume
|
2014-05-07 16:53:23 +00:00
|
|
|
# Daca varsta nu este data, o sa ii atribuim valoarea implicita
|
|
|
|
# din lista de argumente (0, in cazul nostru)
|
2014-03-07 18:09:56 +00:00
|
|
|
@varsta = varsta
|
|
|
|
end
|
|
|
|
|
|
|
|
# Metoda pentru a seta valoarea unei variabile
|
|
|
|
def nume=(nume)
|
|
|
|
@nume = nume
|
|
|
|
end
|
|
|
|
|
|
|
|
# Metoda pentru a lua valoarea unei variabile
|
|
|
|
def nume
|
|
|
|
@nume
|
|
|
|
end
|
|
|
|
|
2014-05-07 16:53:23 +00:00
|
|
|
# Functionalitatea de mai sus poate fi obtinuta
|
|
|
|
# folosing metoda "attr_accessor" dupa cum urmeaza:
|
2014-03-07 18:09:56 +00:00
|
|
|
attr_accessor :nume
|
|
|
|
|
2014-05-07 16:53:23 +00:00
|
|
|
# Metodele pentru a lua si a seta valoarea unei variabile
|
|
|
|
# pot fi de asemenea obtinute individial:
|
2014-03-07 18:09:56 +00:00
|
|
|
attr_reader :nume
|
|
|
|
attr_writer :nume
|
|
|
|
|
2014-05-07 16:53:23 +00:00
|
|
|
# O metoda apartinand unei clase foloseste "self" pentru a se diferentia
|
|
|
|
# de metodele unei instante ale clasei respective
|
2014-03-07 18:09:56 +00:00
|
|
|
# Poate fi invocata doar pe clasa, si nu pe o instanta a acesteia
|
|
|
|
def self.spune(msg)
|
|
|
|
puts "#{msg}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def specie
|
|
|
|
@@specie
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
# Creaza o instanta a unei clase
|
|
|
|
ion = Om.new("Ionut Popescu")
|
|
|
|
|
|
|
|
eugen = Om.new("Eugen Ionescu")
|
|
|
|
|
|
|
|
# Sa invocam niste metode
|
|
|
|
ion.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 clase
|
|
|
|
Om.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 constante
|
|
|
|
Var = "Sunt o constanta"
|
|
|
|
defined? Var #=> "constant"
|
|
|
|
|
2014-05-07 16:53:23 +00:00
|
|
|
# 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
|
2014-03-07 18:09:56 +00:00
|
|
|
|
|
|
|
# clasa parinte
|
|
|
|
class Om
|
|
|
|
@@foo = 0
|
|
|
|
|
|
|
|
def self.foo
|
|
|
|
@@foo
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.foo=(valoare)
|
|
|
|
@@foo = valoare
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# clasa copil
|
|
|
|
class Muncitor < Om
|
|
|
|
end
|
|
|
|
|
|
|
|
Om.foo # 0
|
|
|
|
Muncitor.foo # 0
|
|
|
|
|
|
|
|
Om.foo = 2 # 2
|
|
|
|
Muncitor.foo # 2
|
|
|
|
|
2014-05-07 16:53:23 +00:00
|
|
|
# Variabilele care apartin unei instante ale unei clase,
|
|
|
|
# nu sunt impartite de (copii acesteia) clasele care o extind
|
2014-03-07 18:09:56 +00:00
|
|
|
class Om
|
|
|
|
@bar = 0
|
|
|
|
|
|
|
|
def self.bar
|
|
|
|
@bar
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.bar=(valoare)
|
|
|
|
@bar = valoare
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Doctor < Om
|
|
|
|
end
|
|
|
|
|
|
|
|
Om.bar # 0
|
|
|
|
Doctor.bar # nil
|
|
|
|
|
|
|
|
module ExempluModul
|
|
|
|
def foo
|
|
|
|
'foo'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Incluzand modulul instantei unui obiect
|
|
|
|
# Extinzand modulul unei instante ale unei clase
|
|
|
|
|
|
|
|
class Persoana
|
|
|
|
include ExempluModul
|
|
|
|
end
|
|
|
|
|
|
|
|
class Carte
|
|
|
|
extend ExempluModul
|
|
|
|
end
|
|
|
|
|
|
|
|
Persoana.foo # => NoMethodError: undefined method `foo' for Persoana:Class
|
|
|
|
Persoana.new.foo # => 'foo'
|
|
|
|
Carte.foo # => 'foo'
|
|
|
|
Carte.new.foo # => NoMethodError: undefined method `foo'
|
|
|
|
|
|
|
|
# Callbacks atunci cand includerea si extinderea unui modul sunt executate
|
|
|
|
|
|
|
|
module ModulExempluCallBack
|
|
|
|
def self.included(base)
|
|
|
|
base.extend(ClassMethods)
|
|
|
|
base.send(:include, InstanceMethods)
|
|
|
|
end
|
|
|
|
|
|
|
|
module ClassMethods
|
|
|
|
def bar
|
|
|
|
'bar'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module InstanceMethods
|
|
|
|
def qux
|
|
|
|
'qux'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class CevaRelevant
|
|
|
|
include ModulExempluCallBack
|
|
|
|
end
|
|
|
|
|
|
|
|
CevaRelevant.bar # => 'bar'
|
|
|
|
CevaRelevant.qux # => NoMethodError: undefined method `qux'
|
|
|
|
CevaRelevant.new.bar # => NoMethodError: undefined method `bar'
|
|
|
|
CevaRelevant.new.qux # => 'qux'
|
|
|
|
```
|