Ruby pentru începători Operatorii și metodele lor

Ruby este una dintre cele mai populare limbi folosite pe web. Am inceput o noua serie de screencast-uri aici pe Nettuts +, care va va prezenta Ruby, precum si marile cadre si instrumente care merg impreuna cu dezvoltarea Ruby. În această lecție, vom examina mai profund operatorii din Ruby și de ce diferă de ceea ce ați văzut vreodată.


operatorii

Sunteți familiarizați cu operatorii.

1 + 2 # 3 persoană [: name] = "Joe"

Operatorii sunt lucruri precum semnul plus (unul dintre operatorii aritmetici) sau semnul egal (operatorul de atribuire). Aceste lucruri nu arata mult diferit de cele pe care le folositi in JavaScript, PHP sau orice alta limba. Dar, ca cea mai mare parte a lui Ruby, este mult mai mult decât o întâlnire cu ochiul care merge aici.

Iată secretul: operatorii din Ruby sunt într-adevăr apeluri metodice. Incearca asta:

1. + (2) # 3

Aici sunăm + operator pe obiect 1, trecerea în obiect 2 ca parametru. Obținem obiectul 3. Putem face acest lucru si cu siruri de caractere:

nume = "Joe" nume + "" Smith "#" Joe Smith ", dar" nume "este încă" Joe "

După cum puteți vedea, putem realiza concatenarea șirului cu + metodă. Ca bonus aici, rubinul definește operatorul + = bazat pe operatorul + (notați: nu puteți folosi + = ca metodă).

Așa cum ați putea realiza, acest lucru ne oferă o putere incredibilă. Putem personaliza semnificația adăugării, scăderii și atribuirii obiectelor în clasele personalizate. Am văzut cum funcționează acest lucru cu proprietățile pe obiecte din lecția noastră despre clase (am definit a proprietate și proprietate = în clasă, și a primit sintaxa de zahăr așteptată pentru utilizarea lor). Ceea ce privim aici este să facem un pas mai departe.


Construirea propriilor metode de operare

Sa incercam sa cream singura una din aceste metode. Pentru acest exemplu, să creăm un obiect frigorific, pe care îl putem adăuga prin intermediul + operator și să ia lucrurile din via prin - operator.

Iată începutul clasei noastre:

clasa frigider Definiție inițială (băuturi = [], alimente = []) @ beverages = băuturi @ food = end food def + (item) end def - (item) end end

Al nostru inițializa funcția este destul de simplă: luăm doi parametri (care cad înapoi în matrice goale dacă nu se dă nimic) și le atribuim variabilelor de instanță. Acum, să construim cele două funcții:

def + (element) dacă item.is_a? Băuturi @ băuturi.articolați alt articol @ foods.push sfârșitul elementului

Acest lucru este destul de simplu. Fiecare obiect are un is_a? care ia un singur parametru: o clasă. Dacă obiectul este o instanță a acelei clase, ea va reveni la adevărat; în caz contrar, va reveni fals. Deci, acest lucru spune că dacă elementul pe care îl adăugăm la frigider este a Băutură, o vom adăuga la @beverages matrice. În caz contrar, îl vom adăuga la @alimente mulțime.

Asta e bine; acum, ce zici de a scoate lucrurile din frigider? (Notă: această metodă este diferită de cea prezentată în videoclip, ceea ce vă arată că această metodă de operare ne dă o mare flexibilitate, sunt într-adevăr metode normale cu care puteți face ceva. o versiune mai bună a metodei, însă este mai complexă.)

def - (element) ret = @ beverages.find nu | bautura beverage.name.downcase == item.downcase end return @ beverages.delete ret cu excepția cazului ret.nil? ret = @ foods.find nu | alimente food.name.downcase == item.downcase end @ foods.delete end end

Iată ce se întâmplă când folosim operatorul minus. Parametrul pe care îl are este un șir, cu numele elementului pe care îl căutăm (Apropo, vom crea Băutură și Alimente clase în curând). Începem prin utilizarea funcției găsi metoda pe care o au matricea. Există câteva moduri de a utiliza această metodă; o să-i dăm un bloc; acest bloc spune că încercăm să găsim elementul în matrice care are a Nume proprietatea care este la fel ca șirul în care am trecut; rețineți că convertim ambele șiruri de caractere în litere mici, pentru a fi în siguranță.

Dacă există un element care se potrivește în matrice, acesta va fi stocat în putrezi; in caz contrar, putrezi va fi zero. Apoi, vom returna rezultatul @ beverage.delete ret, care elimină elementul din matrice și îl returnează. Observați că folosim un modificator de declarație la sfârșitul acelei linii: facem asta dacă nu putrezi este zero.

S-ar putea să te întrebi de ce folosim cuvântul cheie întoarcere aici, deoarece nu este necesar în Ruby. Dacă nu l-am folosi aici, funcția nu s-ar întoarce încă, deoarece există mai mult cod pentru această funcție. Utilizarea întoarcere aici ne permite să returnăm o valoare dintr-un loc în care funcția nu s-ar întoarce în mod normal.

Dacă nu ne întoarcem, înseamnă că elementul nu a fost găsit în @beverages. De aceea, presupunem că este înăuntru @foods. Vom face același lucru pentru a găsi elementul în @foods și apoi returnați-o.

Înainte de a testa asta, avem nevoie de noi Alimente și băuturi clase:

clasa băutură attr_accessor: nume def initialize name @name = name @time = Time.now sfârșitul clasei finale Food attr_accessor: nume def initialize name @name = name @time = Time.now end end

Rețineți că în videoclip nu am făcut-o @Nume accesibil din afara obiectului. Aici, eu fac asta cu attr_accessor: nume, astfel încât să putem verifica numele acestor obiecte atunci când sunt în interiorul unui frigider.

Deci, hai să-l testăm în IRB; vom începe prin a solicita fișierul care deține codul; apoi, dați claselor o încercare; rețineți că am adăugat linii de separare la ieșire pentru o citire mai ușoară.

> necesită './lesson_6' => true> f = Fridge.new => # > f + Beverage.new ("apă") => []> f + Food.new ("pâine") => []> f + Food.new ("ouă") => [, # ]> f + Beverage.new ("suc de portocale") => [# #, # ]> f => #, # ], alimente [#, # ]> f - "pâine" => # > f => #, #], alimente [#]

Pe măsură ce mergem, puteți vedea lucrurile care se adaugă la @beverages și @foods și apoi eliminate.


Obțineți și setați operatori

Acum, să scriem metode pentru operatorii de tip get și set folosiți cu hashes. Ați văzut acest lucru înainte:

persoană =  persoană [: name] = "Joe"

Dar, deoarece acești operatori sunt metode, putem face acest lucru:

persoană. [] = (: vârstă, 35) # pentru a seta persoana. [] (: nume) # pentru a obține

Asta e corect; acestea sunt metode normale, cu zahăr special pentru utilizarea dumneavoastră.

Să încercăm; o vom face Club clasă. Clubul nostru are membri cu roluri diferite. Cu toate acestea, am putea dori să avem mai mult de un membru cu un anumit rol. Deci, ale noastre Club instanța va urmări membrii și rolurile lor cu un hash. Dacă încercăm să alocăm un al doilea membru unui rol, în loc să îl suprascriem pe primul, îl vom adăuga.

Class Define inițializează @members =  end def [] (rolă) @members [rol] end def [] = (rol, membru) end end

Versiunea get este destul de simplă; tocmai l-am trimis la @members matrice. Dar setul este un pic mai complicat:

def [] == (rol, membru) dacă @members [role] .nil? @members [role] = Membru elsif @members [role] .is_a? String @members [role] = [@members [role], membru] altceva @members [role] .push end end

Dacă acest rol nu a fost setat, vom seta valoarea acelei chei la hash-ul nostru membru. Dacă a fost setat ca un șir, vrem să îl convertim într-un matrice și să punem membrul original și noul membru în acel matrice. În cele din urmă, dacă niciuna dintre aceste opțiuni nu este adevărată, este deja o matrice și, prin urmare, împingem membrul în matrice. Putem testa această clasă în felul următor:

c = Club.new c [: chair] = "Joe" c [: inginer] = "John" c [: engineer] ", "A da in judecata" ]

Acolo te duci!


Alți operatori

Acestea nu sunt singurii operatori cu care putem face acest lucru, desigur. Iată întreaga listă:

  • Operatori aritmetici: + - * \
  • Obțineți și setați operatori: [] [] =
  • Operatorul lopata: <<
  • Operatori de comparare: == < > <= >=
  • Egalitatea de caz Operator: ===
  • Operator de biți: | & ^

Vă mulțumim că ați citit!

Dacă aveți întrebări despre această lecție sau despre orice altceva discutat în Ruby, întrebați-l în comentariile respective!

Cod