5 esempi di utilizzo ottimale di Ruby
Vi siete mai chiesti cosa possiamo fare con Ruby? Beh, il cielo è probabilmente il limite, ma siamo felici di parlare di alcuni casi più o meno noti...
Prima di iniziare a creare un metodo bang, impariamo che cos'è esattamente questo tipo di metodo e quali sono le sue caratteristiche. Partiamo dal fatto che non esiste una definizione univoca di questo tipo di metodi. In poche parole, un metodo bang è un metodo con un punto esclamativo alla fine.
Spesso ci si imbatte nell'affermazione che il metodo bang è, in un certo senso, un metodo pericoloso e il punto esclamativo alla fine della sua definizione ci dice di essere vigili quando si usa questo metodo. Vediamo: che cos'è esattamente questa minaccia quando si tratta di questi metodi e quali sono le loro caratteristiche?
Una delle caratteristiche più popolari di questi tipi di metodi è che di solito cambiano il loro pubblico. Vediamo il metodo map! come esempio. Secondo la documentazione, il metodo map! invoca il blocco dato una volta per ogni elemento di self, sostituendo l'elemento con il valore restituito dal blocco; se non viene dato alcun blocco, viene invece restituito un Enumeratore.
arry = [1, 2, 3, 4, 5]
arry.object_id => 280
arry.map! {|num|num**num } => [1, 4, 27, 256, 3125]
arry.map! => # [1, 4, 27, 256, 3125]
arry.object_id => 280
Come si può vedere, object_id rimane invariato. Quindi, il pericolo di usare un metodo del genere sembra ovvio. Se nel nostro codice Se abbiamo usato la variabile arry in un altro punto, la mappa! la modificherà. Questo può portare il nostro programma a funzionare in modo indesiderato o addirittura a bloccarsi.
Ci sono oggetti in Rubino che non possono essere modificati, come le istanze delle classi Integer, Float e Symbol. Mentre si lavora su un progetto, si possono incontrare anche i cosiddetti commenti magici che recitano così:
frozenstringa letterale: true
Se si tenta di modificare il destinatario della stringa nel codice in cui è stato utilizzato un commento di questo tipo, si otterrà un errore di questo tipo:
'abc'.upcase!
FrozenError (non è possibile modificare una stringa congelata)
È interessante notare che è stata prevista l'introduzione di Stringhe immutabili in Rubino 3.0, ma si è deciso di non apportare questa modifica. Tuttavia, va ricordato che non tutti i metodi bang modificano il destinatario, quindi è necessario verificare sempre nella documentazione il tipo di pericolo che ci si deve aspettare nel caso di un particolare metodo.
Un'altra caratteristica distintiva di questi metodi è che, per molti di essi, viene sollevata un'eccezione. Un esempio di tale metodo è il metodo ActiveRecord::FinderMethods#first! Secondo la documentazione, il metodo first! è uguale al primo, ma solleva ActiveRecord::RecordNotFound se non viene trovato alcun record. Si noti che first! non accetta argomenti.
File activerecord/lib/activerecord/relation/findermethods.rb, riga 128
def first!
first || raiserecordnotfoundexception!
fine
Tuttavia, il metodo ActiveRecord::FinderMethods#first utilizzato in precedenza ha questo aspetto:
File activerecord/lib/activerecord/relation/findermethods.rb, riga 116
def first(limit = nil)
checkreorderdeprecation a meno che non sia stato caricato?
se limite
findnthwithlimit(0, limit)
altrimenti
findnth 0
fine
fine
Grazie agli esempi precedenti, vediamo il pericolo di usare il primo. Se utilizziamo ActiveRecord::FinderMethods#find! e questo non trova un record adatto nel database, restituirà ActiveRecord::RecordNotFound, il che potrebbe causare l'interruzione del funzionamento del programma.
Tuttavia, dobbiamo ricordare che questo non significa che se un metodo non ha un punto esclamativo alla fine, è sicuro e non solleverà l'eccezione o cambierà il destinatario.
In Ruby on Rails 6.0 è stata introdotta una nuova coppia di metodi: ActiveRecord::Persistence::ClassMethods#insert_all
e ActiveRecord::Persistence::ClassMethods#insert_all!
Il primo di questi metodi mostra già un certo grado di pericolosità. Secondo la documentazione, inserireinserisce più record nel database con un'unica istruzione SQL INSERT. Non istanzia alcun modello e non attiva callback o convalide di ActiveRecord. Tuttavia, l'inserimentoall! solleva inoltre ActiveRecord::RecordNotUnique se qualche riga viola un indice univoco della tabella. In tal caso, non vengono inserite righe. Ciò significa che il primo di questi metodi salverà tutti i record tranne quelli che violano l'indice univoco, mentre il secondo (più pericoloso) solleverà un'eccezione e non salverà alcun record nel database.
Molti metodi, anche se non hanno un punto esclamativo alla fine, sono pericolosi da usare. Ad esempio, ActiveRecord::FinderMethods#find. Secondo la documentazione, se non è possibile trovare uno o più record per gli id richiesti, verrà sollevato ActiveRecord::RecordNotFound.
Si può notare che, sebbene questo metodo abbia lo stesso grado di pericolosità di ActiveRecord::FinderMethods#first!, non ha un punto esclamativo.
Lo stesso vale quando si tratta di modificare il destinatario. Ad esempio, Array.delete (come documentato) cancella tutti gli elementi di self che sono uguali all'oggetto e restituisce l'ultimo elemento cancellato, oppure nil se non vengono trovati elementi corrispondenti.
a = [1, 2, 3, 4, 5]
a.object_id #=> 320
a.delete(2) #=> 2
a #=> [1, 3, 4, 5]
a.delete(6) #=> nil
a.object_id #=> 320
Si vede chiaramente che l'oggetto è stato modificato. Ciò che i due metodi hanno in comune è che non hanno un punto esclamativo equivalente. Pertanto, se il metodo che si vuole creare ha il tipo di pericoli di cui ho parlato sopra, non è necessario che abbia subito un punto esclamativo alla fine. Inoltre, è consigliabile creare un metodo bang se esiste già un metodo con lo stesso nome che è meno pericoloso del metodo che si vuole creare.
Ci si può chiedere perché utilizzare questi metodi pericolosi, soprattutto perché di solito esistono controparti meno pericolose. Uno dei vantaggi può essere, per esempio, il miglioramento delle prestazioni del codice, grazie alla riduzione del numero di oggetti creati. Qui potete leggere ulteriori informazioni su come aumentare le prestazioni di Rails.
Quando si tratta di sollevare eccezioni, l'uso del metodo create invece del pericoloso create! può portare a una situazione in cui un errore nella nostra applicazione è difficile da rilevare, perché i record non vengono scritti nel database. Quindi, se siamo sicuri che i parametri che passiamo a questo metodo sono corretti, dovremmo usare il metodo create!, che solleverà un'eccezione se, per qualche motivo, il record non viene salvato nel database.
La conclusione è semplice: un uso prudente di questi metodi può migliorare le prestazioni e la qualità del nostro codice. Tuttavia, dobbiamo sempre ricordare che un loro uso inappropriato può impedire al codice di funzionare correttamente.
Se si vuole creare un proprio metodo pericoloso, è necessario seguire un certo processo decisionale. Innanzitutto, bisogna chiedersi se esiste già un metodo con lo stesso nome di quello che si vuole creare, ma meno pericoloso. Si può anche pensare di creare una coppia di metodi in cui uno è equivalente all'altro, solo più pericoloso.
Non ha senso creare un metodo bang se non esiste la sua controparte senza punto esclamativo. Ci sono metodi che sono pericolosi perché cambiano l'oggetto o sollevano un'eccezione, eppure non hanno un punto esclamativo alla fine del nome. Creare un metodo bang senza un equivalente confonderebbe un programmatore che utilizza il codice. Questa persona non sarebbe in grado di dire quale sia la pericolosità di questo metodo e perché meriti un punto esclamativo alla fine del nome.
In secondo luogo, occorre considerare di che tipo di pericoli si tratta. Dagli esempi precedenti, possiamo concludere che il tipo di pericolo più comune è la modifica dell'oggetto stesso (invece di crearne una copia) o il sollevamento di un'eccezione. Naturalmente, questa non è una regola, ma piuttosto il risultato dell'analisi dei metodi definiti in Ruby e Ruby on Rails. Ad esempio, si può considerare l'implementazione di una coppia di metodi in cui il metodo senza l'opzione punto esclamativo salverebbe il record nel database, mentre il metodo con il punto esclamativo salterebbe la convalida del record. In questo caso, è chiaro dove risiede il potenziale pericolo dell'uso di tali metodi.
Un riassunto della conoscenza dei metodi bang porta a queste conclusioni: il 1° metodo con il punto esclamativo ha una meno minaccioso
in secondo luogo, il metodo con il punto esclamativo esegue un'azione pericolosa, ad esempio modifica il destinatario o solleva un'eccezione.
In conclusione, la comprensione del concetto di metodi bang in Rubino sviluppo software può migliorare notevolmente le vostre capacità di codifica e dare maggiore chiarezza alla vostra base di codice. Metodi di Bang, indicati da un punto esclamativo alla fine del loro nome, indicano una versione distruttiva o potenzialmente pericolosa di un metodo. Per convenzione, il simbolo controparte bang di un metodo deve essere usato con cautela, perché può modificare gli oggetti direttamente, senza creare una copia separata. Questo può essere particolarmente utile quando si ha a che fare con oggetti mutevoli o quando l'ottimizzazione delle prestazioni è un problema. Tuttavia, è importante fare attenzione quando si usano i metodi bang, perché possono avere conseguenze indesiderate se non vengono gestiti correttamente. Vale anche la pena di notare che non tutti i metodi hanno una funzione versione bange la loro presenza deve essere valutata caso per caso. Conoscendo quando e come creare metodi bang, è possibile utilizzare questo potente strumento in modo efficace e scrivere codice pulito ed efficiente che soddisfi i requisiti specifici.