2012-01-23 13 views
9

Sto entrando in Ruby e provengo dall'ambiente Java e C/C++.È buona pratica avere variabili locali che iniziano con il carattere di sottolineatura?

Durante la codifica di un primo piccolo progetto in Ruby, in qualche modo mi sono abituato a lasciare che tutte le variabili locali inizino con un trattino basso. Immagino che la mia motivazione principale fosse una migliore leggibilità e distinzione dalle chiamate ai metodi.

Come in principio ci sono solo tre tipi di variabili ($global, @instance e local), la maggior parte delle variabili inizia con un trattino basso. Non sono sicuro, se questo è buono o cattivo. Inoltre, in molte altre lingue, il carattere di sottolineatura sarebbe sostituito da un altro personaggio.

C'è in qualche modo una denominazione variabile migliori pratiche riguardante accanto alla solita CamelCase e/o sottolineatura separati? Quali sono le abitudini dei "rubyists" professionali? Ho trascurato alcune convenzioni generali di Ruby, quando ho scelto il trattino basso principale?


modificare
Grazie a tutte le risposte e suggerimenti. Mi ha aiutato molto.


breve riassunto delle risposte e commenti di seguito
(per il visitatore a breve on-time)

sottolineature principali vanno con:

  • metodo argomenti: def my_method(_my_arg)
  • argomenti del blocco: ad es. my_array.each { |_x| puts _x}

Tutte le altre variabili locali senza trattini bassi di sottolineatura, come programmatori provenienti da ad es. JavaScript might get confused sul comportamento previsto delle variabili.

Per la separazione visiva tra i nomi delle variabili e chiamate di metodo, costringendo se stessi per usare "(" staffe ")" con tutte chiamate di metodo potrebbe aumentare in modo significativo la leggibilità.

+1

Ciò che altri linguaggi non sono realmente un problema, perché ogni lingua ha stili di codifica diversi. A volte uso variabili con trattini di sottolineatura principali nei parametri di blocco, ad esempio '{| _a, _b | ...} 'quando voglio farli risaltare, o rende il codice più leggibile. La leggibilità si traduce in mantenibilità nel tempo, quindi vai con quello che scorre dentro e fuori i tuoi occhi e la testa più facile. –

+0

@theTinman: Underscores con argomenti di blocco sembra anche un modo ragionevole. Grazie per quello. –

+0

@Torbjoern grazie per il breve riassunto, molto utile – ramzyo

risposta

1

Niente di sbagliato con la tua idea. Ma se avessi difficoltà a distinguere le vars locali dalle chiamate ai metodi, probabilmente mi costringerei a usare sempre i metodi (). (Il mio team al lavoro ha discusso di rendere questa parte dei nostri standard di codifica).

a = thing # var 
b = thing() # method 

Il vantaggio possibile è la leggibilità per gli altri. Qualcuno potrebbe chiedersi le tue iniziali, ma usare () su tutte le chiamate di metodo dovrebbe essere chiaro a tutti.

+0

Usi le parentesi solo con le chiamate di metodo senza argomenti o con ** tutte le chiamate al metodo ** indipendentemente dal numero di argomenti che vengono passati? –

+0

Con ** tutte ** chiamate di metodo. (In realtà non sono così severo, ma alcune persone al lavoro ci stanno spingendo, e penso che potrebbe essere utile in casi come sopra.) – bioneuralnet

+0

Ma l'intero codice non è troppo affollato molto presto? Ma questo porta ad un'altra discussione sull'introduzione di spazi bianchi, e non c'è ** l'unica soluzione. –

3

Nella mia esperienza, le variabili con prefisso sottolineato in Ruby sono molto simili a variabili prefissate in JavaScript: un flag "non toccare". Più specificamente, vengono usati quando l'implementatore sta facendo qualcosa che non dovrebbe essere inteso come parte dell'oggetto, o non dovrebbe essere pensato come l'interfaccia concettuale dell'oggetto.

Questo è più chiaro nel mondo JavaScript, dove qualcuno emula "privato" prefiggendo una variabile con un trattino basso. Stanno codificando che c'è una parte dell'oggetto che è sotto il cofano e può essere ignorata quando si guarda l'oggetto dall'esterno.

In Ruby, l'ho visto solo con cose come una cache o un'istanza singleton, il tipo di cosa che dovrebbe essere invisibile ai consumatori del tuo oggetto. Le variabili non sottolineate sono cose che le persone che usano il tuo oggetto potrebbero essere interessate a sapere che ci sono.

In ogni caso, sembrano abbastanza rari, e vorrei evitarli a meno che non vogliate inviare un segnale al prossimo che sta arrivando che ci sia un po 'di magia o di voodoo in più.

Per fare una distinzione per le chiamate di metodo, se si è preoccupati che possa esserci confusione tra un metodo e una variabile locale, chiamare il metodo su self per chiarire. Per esempio:

def foo 
    ... 
end 

def some_method 
    foo # method 
    bar # variable 
end 

Se questo vi sembra poco chiaro per qualsiasi motivo, è possibile chiarire con

def some_method 
    self.foo 
    bar 
end 
+0

Grazie. Ma immagino che usare "self" per le chiamate al metodo possa confondermi. Non è 'def self.foo' una definizione di un metodo di classe (non di istanza)? Dato che uso molto raramente, un "io" attirerà la mia attenzione e mi fa pensare che mi trovo di fronte a una definizione di metodo di classe. –

+0

Sì, lo è, ma la chiave è capire l'ambito di "sé". Ricorda, in Ruby, tutto è un oggetto, ad esempio in C++, non esiste qualcosa come un oggetto di classe, solo le istanze create da una definizione di classe. In pratica, in fase di esecuzione, non esiste una classe, solo una raccolta di metodi attorno a un insieme comune di dati. Nel rubino, anche le classi sono esempi. Quando definisci la classe, 'self' è questa istanza _class_, e quando sei in un metodo,' self' è la _istanza_ di quella classe. So che questo è fonte di confusione - è difficile spiegare ... – Matt

+0

Non so, se è difficile da spiegare. Per me è piuttosto logico e conseguente come è fatto in Ruby. Comunque, grazie per aver cercato di chiarirlo :) –

1

Visto che le variabili di istanza sono il segno @ di fronte a loro, e le variabili globali hanno il segno $ di fronte a loro già in ruby, probabilmente non è necessario mettere un carattere di sottolineatura davanti ai nomi delle variabili. Detto questo, non penso che sia necessariamente una cattiva pratica. Se ti aiuta a leggere o scrivere il tuo codice in Ruby, dovresti usarlo.

A volte ho visto il codice Ruby dove un argomento per un metodo di istanza su una classe ha un trattino di sottolineatura di fronte ad esso. Come ad esempio:

def my_method(_argument1) 
    # do something 
end 

E penso che quando hai a che fare con una classe che può avere è di possedere gli attributi, come un file di modello di rotaie, per esempio, questo può essere utile in modo che si sa che si sta trattando una variabile che è stata passata nel metodo in contrasto con uno degli attributi che appartengono alla classe/modello.

+1

L'uso dei caratteri di sottolineatura solo con gli argomenti del metodo, sembra essere una buona cosa. Grazie per aver condiviso questo. –

+0

Se i tuoi metodi sono così lunghi che l'elenco dei parametri non è più visibile sullo schermo, non dovresti splatterli con caratteri di sottolineatura, devi ridimensionarli per essere più piccoli. –

+0

@ JörgWMittag - Se leggi la mia descrizione, non ho detto nulla sulla lunghezza dei metodi o sul numero di parametri, ho semplicemente detto che può essere utile quando si scrive un metodo di istanza di classe per differenziare che queste variabili sono argomenti per il metodo come opposto a un metodo o attributo della classe stessa. Ancora una volta, non è necessario ma a volte può essere utile. – Batkins

3

Le risposte esistenti a questa domanda hanno ormai alcuni anni e le convenzioni sono cambiate. Dovresti sempre usare solo un trattino basso (_some_param) o un trattino basso indipendente (_), per indicare che non ti interessa il valore. Lo strumento di linting dello stile rubocop si occuperà di un "inutile compito" se assegni una variabile ma non la usi, ma ignorerà le variabili con un trattino di sottolineatura principale. Questo ti consente di indicare espressamente che non ti importa del valore e non intendi usarlo.

Ecco un esempio un po 'artificiosa-casi d'uso in un contesto RSpec:

describe 'login' do 
    let(:user) { FactoryGirl.create(:user, login: 'bob') } 
    it 'must be unique' do 
    _user1 = user 
    user2 = User.new login: 'bob' 
    expect(user2.valid?).to be_false 
    end 
end 

Qui stiamo indicando che la nostra user Memoizzazione aiuto ha un effetto collaterale e restituisce qualcosa, ma non ci interessa a proposito.Si potrebbe anche saltare l'assegnazione del tutto, ma vedere una nuda user su una riga da solo sembra strano e non rivela l'intenzione nel modo più chiaro:

describe 'login' do 
    let(:user) { FactoryGirl.create(:user, login: 'bob') } 
    it 'must be unique' do 
    user 
    user2 = User.new login: 'bob' 
    expect(user2.valid?).to be_false 
    end 
end 

Altri scenari sono ignorando i valori di iteratori, o l'override un metodo in cui si desidera mantenere la firma del metodo originale ma non si preoccupa di alcuni valori:

def greet(name, _title) 
    puts "Hi, #{name}!" 
end 
+1

Il modo più comune per te ' Lo vedremo tramite l'assegnazione parallela di 'Array'. per esempio. se una funzione "restituisce 3 valori" (in realtà un 'Array' di lunghezza 3) e non si ha intenzione di utilizzare la prima variabile, si può scrivere: ' _, myvar2, myvar3 = three_arg_function' o '_myvar1, myvar2, myvar3 = three_arg_function' – supermoogle

Problemi correlati