Qual è lo scopo di "!" e "?" alla fine dei nomi dei metodi?


Risposte:


160

È "solo rivestimento di zucchero" per la leggibilità, ma hanno significati comuni:

  • Metodi che terminano con l' !esecuzione di modifiche permanenti o potenzialmente pericolose ; per esempio:
    • Enumerable#sortrestituisce una versione ordinata dell'oggetto mentre lo Enumerable#sort!ordina in posizione.
    • In Rails, ActiveRecord::Base#saverestituisce false se il salvataggio non è riuscito, mentre ActiveRecord::Base#save!solleva un'eccezione.
    • Kernel::exitfa sì che uno script esca, mentre lo Kernel::exit!fa immediatamente, bypassando qualsiasi gestore di uscita.
  • I metodi che terminano con ?un valore booleano , che rende il flusso di codice ancora più intuitivo come una frase: si if number.zero?legge come "se il numero è zero", ma if number.zerosembra strano.

Nel tuo esempio, name.reverserestituisce una stringa invertita, ma solo dopo la name.reverse!riga la namevariabile contiene effettivamente il nome invertito. name.is_binary_data?sembra "sono namedati binari?".


22
Una nota importante è che dovresti avere un metodo bang solo se hai anche un metodo non bang corrispondente. Il botto viene utilizzato per distinguere la versione "più sorprendente" del metodo da quella "meno sorprendente". Se disponi di un solo metodo, non è necessaria alcuna distinzione e non dovresti nominarlo con il botto. Vedi Array#clear, per esempio. Cancella l'array. La cancellazione dell'array lo modifica naturalmente. Non c'è niente di sorprendente in questo, già il nome lo dice chiaramente, quindi: niente botto. Vedi ruby-forum.com/topic/176830#773946 .
Jörg W Mittag

2
In aggiunta a quanto affermato da @ JörgWMittag, secondo la Ruby Style Guide : i nomi dei metodi potenzialmente pericolosi (cioè i metodi che modificano self o gli argomenti, exit! (Non esegue i finalizzatori come fa exit), ecc.) Dovrebbero terminare con un punto esclamativo se esiste una versione sicura di quel metodo pericoloso .
Tod Birdsall

2
Attenzione, non è sempre così. Ad esempio, Ruby Array # concat docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat . Dove puoi scottarti gravemente è qualcosa come MyActiveRecordModel.column_names.concat (...). Invece devi clonarlo prima di eseguire il concat.
mercoledì


8

In Ruby ?significa che il metodo restituirà un booleano e !modificherà l'oggetto su cui è stato chiamato. Sono lì per migliorare la leggibilità quando si guarda il codice.


5

In contrasto con - suppongo - la maggior parte dei linguaggi di programmazione ...

Ruby, i metodi possono terminare con punti interrogativi o punti esclamativi.

Per convenzione, i metodi che rispondono alle domande (ad esempio Array # empty? Restituisce true se il ricevitore è vuoto) terminano con punti interrogativi.

I metodi potenzialmente "pericolosi" (cioè i metodi che modificano se stessi o gli argomenti, escono! Ecc.) Per convenzione terminano con punti esclamativi.

Da: http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/ , sezione Nomi metodi divertenti


1
Anche i metodi che terminano con ?sono chiamati metodi predicato.
Waseem

1

Attenzione, non è sempre così. Prendiamo ad esempio Ruby Array # concat http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat .

Dove puoi bruciarti gravemente è qualcosa di simile MyActiveRecordModel.column_names.concat([url]). Le chiamate successive relative a MyActiveRecordModel proveranno a cercare una colonna di "url" per MyActiveRecordModel e lanciano.

Invece devi clonarlo prima di eseguire il concat. Fortunatamente la mia suite di test ha rilevato questo, ma .. avvertite!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.