Poiché non vi è alcun tipo in ruby, in che modo i programmatori di Ruby si assicurano che una funzione riceva argomenti corretti? In questo momento, sto ripetendo le dichiarazioni if object.kind_of
/instance_of
per verificare e aumentare gli errori di runtime ovunque, il che è brutto. Ci deve essere un modo migliore per farlo.Come fanno i programmatori Ruby a digitare il controllo?
risposta
Ruby è, naturalmente, digitato in modo dinamico.
Pertanto la documentazione del metodo determina il tipo di contratto; l'informazione sul tipo viene spostata dal sistema di tipo formale alla [specifica del tipo informale nella documentazione del metodo]. Io mescolo le generalità come "agisce come un array" e specifiche come "è una stringa". Il chiamante dovrebbe aspettarsi di lavorare solo con i tipi dichiarati.
Se il chiamante viola questo contratto, può succedere di tutto. Il metodo non deve preoccupare: è stato usato in modo errato.
Alla luce di quanto precede, evitare controllo per un tipo specifico e evitare cercando di creare sovraccarichi con tale comportamento.
I test unitari possono help assicurarsi che il contratto funzioni per i dati previsti.
@cjk Sebbene questo sia un buon paradigma da seguire, non risponde ancora alla domanda. Suggerisco di accettare invece la risposta di Sawa. – anthropomorphic
Il mio modo personale, che non sono sicuro se è un modo consigliato in generale, è di controllare il tipo e fare altre convalide una volta che si è verificato un errore. Ho inserito la routine di controllo del tipo in un blocco di salvataggio. In questo modo, posso evitare la perdita di prestazioni quando vengono forniti gli argomenti corretti, ma comunque restituire il messaggio di errore corretto quando si verifica un errore.
def foo arg1, arg2, arg3
...
main_routine
...
rescue
## check for type and other validations
raise "Expecting an array: #{arg1.inspect}" unless arg1.kind_of?(Array)
raise "The first argument must be of length 2: #{arg1.inspect}" unless arg1.length == 2
raise "Expecting a string: #{arg2.inspect}" unless arg2.kind_of?(String)
raise "The second argument must not be empty" if arg2.empty?
...
raise "This is `foo''s bug. Something unexpected happened: #{$!.message}"
end
Supponiamo nel main_routine
, si utilizza il metodo each
su arg1
supponendo che arg1
è un array. Se risulta che è qualcos'altro, a cui each
non è definito, il messaggio di errore nudo sarà qualcosa come method each not defined on ...
, che, dal punto di vista dell'utente del metodo foo
, potrebbe non essere utile. In tal caso, il messaggio di errore originale verrà sostituito dal messaggio Expecting an array: ...
, che è molto più utile.
Il problema con questo però è che l'errore * real * potrebbe essere mascherato a causa di uno degli altri problemi rilevati. Quindi, mentre potrebbe * anche * essere un problema, potrebbe non essere correlato a ciò che è stato effettivamente sollevato. Se si eseguirà il controllo esplicito del tipo, farlo * prima *, non in fase di ripristino. –
Perché usi '# {arg1}' invece di '# {arg1.inspect}'? O in modo più specifico, '" Aspettando una stringa: # {arg2} "' invece di '" Aspettando una stringa: # {arg2.inspect} "'? –
@pst Ciò può essere evitato mettendo un altro 'raise' alla fine mentre ho modificato. Se viene sollevato un errore interno a 'pippo', ma tutti i passaggi di convalida, allora è il caso che il controllo di validazione non sia stato sufficiente o che ci sia un bug interno a' pippo'. – sawa
Se un metodo ha un motivo per esistere, verrà chiamato.
Se vengono scritti test ragionevoli, verrà chiamato tutto.
E se ogni metodo viene chiamato, allora ogni metodo verrà controllato.
Non sprecare tempo inserendo controlli di tipo che potrebbero limitare inutilmente i chiamanti e duplicheranno comunque il controllo di runtime. Spendi quel tempo per scrivere invece i test.
vi consiglio di usare rilancio all'inizio del metodo per aggiungere il tipo controllo manuale, semplice ed efficace:
def foo(bar)
raise TypeError, "You called foo without the bar:String needed" unless bar.is_a? String
bar.upcase
end
miglior modo quando non si dispone di molto i parametri, anche una raccomandazione è di usare parole chiave argomenti disponibili su Ruby 2+ se si hanno più parametri e si osservano i dettagli di implementazione attuali/futuri, stanno migliorando la situazione, dando al programmatore un modo per vedere se il valore è zero.
più: è possibile utilizzare un'eccezione personalizzata
class NotStringError < TypeError
def message
"be creative, use metaprogramming ;)"
#...
raise NotStringError
È possibile utilizzare un approccio Design by Contract, con la gemma contracts rubino. Lo trovo molto carino
- 1. Controllo versione per non programmatori
- 2. Qual è il significato per i programmatori di Ruby della nuova implementazione di SAP di Ruby?
- 3. Come digitare il suggerimento
- 4. Perché i programmatori a volte si riferiscono a "C++/STL" come se fosse una lingua separata?
- 5. inclusi i moduli a controllo
- 6. Il miglior software per calcolatori per aiutare i programmatori
- 7. Il modo migliore per i programmatori di modificare XAML
- 8. Estensione Google Wave per i programmatori e il loro codice
- 9. Due domande per i vecchi programmatori
- 10. I programmatori dovrebbero allenarsi in concorsi ACM?
- 11. Siti per i programmatori Delphi iniziali
- 12. Cosa intendono i programmatori funzionali per "morale"?
- 13. Perché l'importazione di Control.Applicative consente a questo codice errato di digitare il controllo?
- 14. Digitare il codice USSD?
- 15. Digitare il combinatore Y
- 16. Come digitare il cast in F #?
- 17. Modellazione 3D per programmatori
- 18. Come digitare il numero negativo con .isdigit?
- 19. Come digitare il testo in una casella combinata?
- 20. Ruby supporta l'unicode e come funziona?
- 21. Tutorial MATLAB per programmatori
- 22. Come posso convincere i programmatori del mio team a fare TDD?
- 23. Programmatori Dragon NaturallySpeaking
- 24. Perché i compressori js non lo fanno?
- 25. Cosa fanno i comandi ft in Vim?
- 26. Come faccio a convincere ruby-prof a ignorare i metodi core/gemma/core standard di Ruby?
- 27. PHP per programmatori Python?
- 28. I documenti dovrebbero essere scritti dai programmatori esperti?
- 29. Cosa fanno effettivamente i file pdb?
- 30. Come posso spiegare il controllo del codice sorgente (Mercurial/Tortoise in modo specifico) a un non programmatore?
Perché è necessario assicurarsi che l'input sia di un tipo specifico? Le funzioni fanno quello che viene detto e non dovrebbero essere forzate a digitare check. – Blender
cercare "duck-typing" –
@Blender Eg. setNextNode (link) .In questa funzione se non ho un controllo di tipo tutto può essere passato in ... Sto facendo un incarico ora e mi è stato detto di fare il controllo del tipo e assicurarmi la sicurezza del runtime. – kun