Utilizzando i simboli Ruby

La prima volta che ho provato a imparare Ruby era 2 anni fa, ora ho ricominciato. Il motivo per cui ho smesso era perché non riuscivo a capire la class Symbol. E ora sono di nuovo nello stesso punto, completamente perso nel momento in cui e perché usi i Simboli. Ho letto gli altri post su Stackoverflow e su Google per diverse spiegazioni. Ma non lo capisco ancora.

Innanzitutto pensavo che i simboli fossero solo un modo per creare una sorta di “costante di nome” senza dover passare attraverso lo stesso processo come diciamo Java.

:all 

invece di fare una costante con un valore arbitrario public static final String ALL = 8;

Tuttavia non ha molto senso quando lo si utilizza ad es. attr_accessor :first_name etc. I simboli sono solo una class String leggera? Sto avendo problemi a capire come dovrei interpretare, quando e come usare i simboli sia nelle mie classi che nei framework.

In breve, i simboli sono stringhe leggere, ma sono anche immutabili e non raccoglibili.

Non dovresti usarli come stringhe immutabili nelle tue attività di elaborazione dati (ricorda, una volta che il simbolo è stato creato, non può essere distrutto). Generalmente usi i simboli per nominare le cose.

 # typical use cases # access hash value user = User.find(params[:id]) # name something attr_accessor :first_name # set hash value in opts parameter db.collection.update(query, update, multi: true, upsert: true) 

Prendiamo il primo esempio, params[:id] . In un’app rotaie moderatamente grandi ci possono essere centinaia / migliaia di quelli sparsi nella base di codice. Se abbiamo accesso a quel valore con una stringa, params["id"] , significa che ogni volta viene assegnata una nuova allocazione di stringhe (e che la stringa deve essere raccolta in seguito). In caso di simbolo, è in realtà lo stesso simbolo ovunque. Meno lavoro per allocatore di memoria, garbage collector e anche tu ( : è più veloce da digitare di "" )

Se hai una semplice stringa di una sola parola che appare spesso nel tuo codice e non fai qualcosa di funky (interpolazione, gsub, upcase, ecc.), Allora è probabile che un buon candidato sia un simbolo.

Tuttavia, questo si applica solo al testo che viene utilizzato come parte della logica del programma reale come la denominazione, non il testo che si ottiene durante l’esecuzione del programma … come il testo da parte dell’utente / web, ecc?

Non riesco a pensare a un singolo caso in cui vorrei convertire i dati da utente / web a simbolo (eccetto per l’analisi delle opzioni da riga di comando, forse). Soprattutto a causa delle conseguenze (una volta creati i simboli vivono per sempre).

Inoltre, molti editor forniscono colors diversi per i simboli, per evidenziarli nel codice. Dai un’occhiata a questo esempio

simbolo vs stringa

L’O’Reilly Ruby Cookbook (pagina 15) cita Jim Weirich come dicendo:

  • Se il contenuto (la sequenza di caratteri) dell’object è importante, usa una stringa.
  • Se l’id quadro dell’object è importante, usa un simbolo.

I simboli sono generalmente usati come chiavi hash, perché è l’ id quadro della chiave che è importante. I simboli sono anche richiesti quando si passano messaggi usando determinati metodi come Object # send .

Un’implementazione di Ruby in genere ha una tabella in cui memorizza i nomi di tutte le classi, i metodi e le variabili. Si riferisce a dire un nome di metodo dalla posizione nella tabella, evitando costosi confronti tra stringhe. Ma puoi usare anche questa tabella e aggiungere valori ad essa: symbols .

Se si scrive codice che utilizza le stringhe come identificatori piuttosto che per il loro contenuto testuale, prendere in considerazione i simboli. Se scrivi un metodo che si aspetta che un argomento sia “maschile” o “femmina”, considera l’utilizzo di :male e :female . Il confronto di due simboli per l’uguaglianza è più rapido delle stringhe (ecco perché i simboli fanno buone chiavi di hash).

I simboli sono usati per denominare le cose nella lingua: i nomi delle classi, i nomi dei metodi, ecc. Sono molto simili alle stringhe, tranne che non possono mai essere raccolti e il test per l’uguaglianza è ottimizzato per essere molto veloce.

L’implementazione Java ha una cosa molto simile, tranne per il fatto che non è disponibile per l’utilizzo in runtime. Quello che voglio dire è che quando scrivi codice java come obj.someMethod(4) , la stringa “someMethod” viene convertita dal compilatore in un simbolo che è incorporato in una tabella di ricerca nel file .class. Questi simboli sono come stringhe “speciali” che non sono raccolte dalla spazzatura e che sono molto veloci da confrontare per l’uguaglianza. Questo è quasi identico a Ruby, tranne per il fatto che Ruby ti permette di creare nuovi simboli in fase di esecuzione, mentre Java lo consente solo in fase di compilazione.

Questo è come creare nuovi metodi: Java lo consente in fase di compilazione; Ruby lo consente in fase di runtime.