Una delle prime lingue che ho imparato è Pascal. Aveva un'importante distinzione che era stata fatta. C'erano procedure , che non avevano alcun ritorno, e funzioni che sempre ha avuto un tipo di ritorno.
Questi sono due costrutti separati che separano le cose.
Funzioni restituiscono valori. Sempre.
Ora che questo è fuori strada, un metodo (sia esso funzionale o procedurale) dovrebbe sempre restituire qualcosa che sia significativo se deve restituire qualcosa. Restituire valori che sono scartati al 99% o al 100% delle volte non è utile - è uno spreco. Un buon compilatore potrebbe riconoscerlo e potrebbe rendere il suo minimo se il ritorno non costa nulla ... ma lo spreco è nel tempo umano per la persona che legge il codice. Cosa sta restituendo? Perché sta tornando?
Molti strumenti di analisi statica avvertiranno (correttamente) il programmatore circa la possibilità di ignorare il valore di ritorno di una chiamata di funzione. Ad esempio FindBugs
This method ignores the return value of one of the variants of java.io.InputStream.read()
which can return multiple bytes. If the return value is not checked, the caller will not be able to correctly handle the case where fewer bytes were read than the caller requested. This is a particularly insidious kind of bug, because in many programs, reads from input streams usually do read the full amount of data requested, causing the program to fail only sporadically.
Oppure gli avvisi in g ++ (# 534)
Ignoring return value of function 'Symbol' (compare with Location)
A function that returns a value is called just for side effects as, for example, in a statement by itself or the left-hand side of a comma operator. Try: (void) function( ); to call a function and ignore its return value. See also the fvr, fvo and fdr flags.
E quindi, c'è l'aspettativa che dovrebbe stare guardando ai valori di ritorno che vengono restituiti. Se non ha significato, non dovrebbe essere al primo posto. Se si tratta di un errore eccezionale, beh, questo è ciò che le eccezioni sono (in molte lingue).
Ora, vediamo qualcosa su questo codice:
class Person:
def __init__(self, name):
self.name = name
def set_name(self, new_name):
return ' '.join(s[0].upper() + s[1:] for s in new_name.split(' '))
def __main__():
me = Person('Foo')
me.name = me.set_name('foo bar')
Vedi quelle linee che ho chiamato? Non stanno facendo quello che dicono che stanno facendo affatto .
La funzione denominata set non è impostata. La sua formattazione, ma non è impostata.
Certo, scrivere format_name
non è un metodo sbagliato per scrivere. E sarebbe una funzione - perché restituisce qualcosa. E a (perdonare il mio Java) public void setName(String name)
ha un tipo di ritorno void
- perché non è utile a nessuno. Comunica chiaramente il suo intento: "Sto impostando questo valore e il suo risultato. Non ti preoccupare".
I metodi dovrebbero avere solo utili valori di ritorno.