|
Este minunat sa poti lucra cu datele in forma lor elementara, dar toti stiu ca partea amuzanta se afla in cadrul colectiilor.
O colectie de date (denumita uneori container) reprezinta un obiect ce contine un grup de elemente inrudite; aceasta relatie poate fi dupa tip (de exemplu toate elementele continute sunt siruri de caractere), scop (de exemplu toate sunt nume) sau dupa sortimentul de branza favorit (al meu este provolone). O colectie poate fi utilizata pentru a gazdui un numar de articole, de a le pastra organizate si de a efectua operatiuni asupra membrilor; in acelasi timp, fiecare membru (sau element) al colectiei este un obiect separat, vizibil, asupra caruia se poate opera (de ex. poate apela metode, poate fi adunat sau se poate scadea etc.).
Intervalul
Primul si cel mai elementar tip de colectie este intervalul. Intervalele detin o secventa de valori cum ar fi toate numerele intre 1 si 9 sau literele de la A la Z. Un interval este creat prin plasarea unei serii de puncte intre limita superioara si cea inferioara a intervalului. De exemplu, daca ai fi creat un joc pe roluri si ai fi vrut sa setezi intervalele posibile ale inaltimii fiecarei rase (in inch) ai scrie:
om = 48..81
elf = 40...68
monstru = 120..132
Intervalele pot utiliza fie doua puncte, care indica un interval inchis ce contine valoarea initiala si pe cea finala, sau trei puncte, excluzand ultima valoare. Aceasta pare pe dos la prima vedere, dar poti gandi ca cel de-al treilea punct este atat de mare incat impinge ultimul element in afara intervalului. Nu glumesc; deschide un debugger si vei afla singur. De exemplu, intervalul 1...7 va crea un interval precum urmatorul:
Pe de alta parte, intervalul 1..7 va crea:
Acum ca poti aseza valorile corect intr-un interval, poate ca vrei sa si faci ceva cu ele. Intervalele ofera cateva metode pentru a le testa si compara. Mai intai, poti compara intervale utilizand operatorul == sau metoda eql?. Daca ar trebui sa scrii software pentru a administra vanzarile din panificatie (am auzit ca reprezinta o piata infloritoare in industria software acum), atunci poate vei dori sa scrii un cod de test pentru a verifica probabilitatea intervalului prajiturilor bune si rele pe care le poti obtine intr-un lot:
prajituri_bune = 1...3
prajituri_rele = 1..3
prajituri_arse = 1..3
puts(prajituri_bune == prajituri_rele) -> false
puts(prajituri_bune.eql?(prajituri_arse)) -> false
puts(prajituri_rele == prajituri_arse) -> true
Intervalele sunt considerate egale daca valorile lor initiale si finale sunt aceleasi, dar observa ca desi prajituri_bune si prajituri_rele au aceleasi valori initiale si finale in cod, valoarea lor difera. Valorile au fost schimbate de marcajul inclusiv (iti amintesti partea cu doua si respectiv trei puncte?). Valorile pentru prajituri_bune sunt [1,2] in timp ce prajituri_rele detin [1,2,3].
Intervalele ofera de asemenea modalitatea de a testa daca o valoare este sau nu continuta intr-un interval cu ajutorul operatorului === sau cu metoda include?. De exemplu, daca tu si prietenul tau ati ghicit un numar de prajituri bune, dar ati vrea sa vedeti daca numarul se afla in intervalul probabil de prajituri bune, ati putea face acest lucru astfel:
nr_meu = 2
nr_prietenului = 19
puts(prajituri_bune === nr_meu) -> true
puts(prajituri_bune.include?( nr_meu)) -> true
puts(prajituri_bune === nr_prietenului) -> false
Metoda include? va returna true pentru orice valoare care este cuprinsa in interval (de exemplu, daca ai fi testat 2.44564 pentru prajituri_rele s-ar intoarce true); Daca te simti putin schimbator, poti incerca un echivalent al metodei include?: member?.
Array-ul
Cea de-a doua colectie inclusa este array-ul sau vectorul, ce reprezinta un sir de elemente ordonate si indexate. Daca ai participat la un curs introductiv de informatica, conceptul de array nu ar trebui sa-ti fie strain, insa implemetarea Ruby poate sa-ti para usor nefamiliara. Spre deosebire de C/C++ si Java unde indexarea porneste de la 0 (de ex. primului element ii este atribuit indicele 0, celui de-al doilea element 1, si asa mai departe) si elementele dintr-un vector sunt de acelasi tip, elementele dintr-un array Ruby nu trebuie sa fie de acelasi tip; nici macar tipul de array nu trebuie specificat inainte de a fi initializat pentru utilizare. Deci, ai putea ajunge la un array asemanator acestuia:
In Ruby, pot fi create array-uri literale care pot fi populate in diverse moduri interesante si amuzante:
array_gol = []
alt_array_gol = Array.new
hello = ['ni hao', 'bonjour', 'hi', 'howdy']
tipuri_aleatorii = [13, 'napkin', (1336 + 1).to_s]
Un array poate fi initializat cu valori de orice tip, chiar si cu variabile, valori returnate de metode, literali cum ar fi siruri de caractere sau nimic (pentru a crea un array gol). Acest lucru este util mai ales pentru valorile literale, dar Ruby mai ofera cateva metode pentru crearea de array-uri care sunt mai convenabile si cu siguranta mai "Rubyrifice". Stringurile ofera un mod special de a crea array-uri din propriul continut. Sa presupunem ca scrii haiku si ca vrei sa te asiguri ca fiecare linie (care este convenabil umpluta cu cuvinte monosilabice) se potriveste tiparului "5-7-5" prin divizarea liniei intr-un array astfel incat sa poti numara elementele:
vers_haiku = %w( my dog digs it here\n )
-> ["my", "dog", "digs", "it", "here" ]
vers_haiku = %w( he is nice to me & cats\n )
-> ["he", "is", "nice", "to", "me", "&", "cats"]
vers_haiku = %W( but he ate #{(2*3)/6} once )
-> ["but", "he", "ate", "1", "once"]
vers_haiku = %w( but he ate #{(2*3)/6} once )
-> ["but", "he", "ate", "#{(2*3)/6}", "once"]
Oh! Un string infasurat in delimitatorul %W se comporta ca un sir cu ghilimele, adica efectueaza interpolarea stringului si substituie secventele escape, iar delimitatorul %w actioneaza ca un string cu apostrofi: permite utilizarea unui subset de secvente escape si nu faciliteaza interpolarea. Unii sunt zapaciti de toata aceasta vorbarie, dar este extrem de usor de retinut: este mai bine sa folosesti majuscula W (cu exceptia cazului in care nu ai nevoie de toate caracteristicile fantezie sau daca ai un fel de convingeri religioase impotriva ghilimelor duble si/sau a literei mari W).
Ultima modalitate de a forma array-uri pe care as dori sa o mentionez este metoda to_a a unor obiecte. Aceasta metoda converteste un obiect sau (rareori) pe unul dintre membrii sai intr-un array. De exemplu, intervalele suporta aceasta metoda:
intervalul_meu = 1..10
-> 1..10
array_din_interval = intervalul_meu.to_a
-> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|