2010-05-08 10 views
11

Mi chiedo se la scrittura di funzioni come questa è considerata buona o cattiva forma.Restituzione di vero o messaggio di errore in Ruby

def test(x) 
    if x == 1 
     return true 
    else 
     return "Error: x is not equal to one." 
    end 
end 

e quindi di utilizzare lo facciamo qualcosa di simile:

result = test(1) 

if result != true 
    puts result 
end 

result = test(2) 

if result != true 
    puts result 
end 

Il che viene visualizzato il messaggio di errore per la seconda chiamata per testare.

Sto pensando di farlo perché in un progetto di rotaie sto lavorando all'interno del mio codice controller faccio chiamate ai metodi di istanza di un modello e se qualcosa va storto voglio che il modello restituisca il messaggio di errore al controller e il controller prende quel messaggio di errore e lo inserisce nel flash e reindirizza. Un po 'come questo

def create 
    @item = Item.new(params[:item]) 

    if [email protected]? 
     result = @item.save_image(params[:attachment][:file]) 

     if result != true 
      flash[:notice] = result 

      redirect_to(new_item_url) and return 
     end 

     #and so on... 

In questo modo non sto costruendo i messaggi di errore nel controller, semplicemente li passando lungo, perché io davvero non voglio il controller di essere preoccupati con ciò che il metodo in sé save_image fa proprio se o non ha funzionato.

Ha senso per me, ma sono curioso di sapere se questo è considerato un metodo buono o cattivo di scrivere metodi. Tenete a mente che lo sto chiedendo nel senso più generale che riguarda principalmente il rubino, succede solo che lo sto facendo in un progetto di rotaie, la vera logica del controller in realtà non è la mia preoccupazione.

+1

Rubino di solito usa 2 spazi per il rientro, non 4. –

risposta

21

Direi che i metodi che restituiscono diversi tipi (ad esempio, booleano vs stringa vs. numeri) in circostanze diverse sono una cattiva pratica.

Se si dispone di una sorta di metodo di prova che vuole tornare dettagli del perché il test non ha superato allora si può tornare una coppia di valori (un Array) come segue:

def test(x) 
    if x == 1 
     return true, "x is fine" 
    else 
     return false, "Error: x is not equal to one." 
    end 
end 

e poi scrivere il sezione del codice del controller come:

valid, message = @item.save_image(params[:attachment][:file]) 

if !valid 
    flash[:notice] = message 
    redirect_to(new_item_url) and return 
end 

Se si sta parlando di un metodo save_image che riuscirà la maggior parte del tempo, ma potrebbe non riuscire e si desidera indicare questo fallimento e la ragione quindi vorrei usare exceptions, ad es.

def save_image(file) 
    raise "No file was specified for saving" if file.nil? 
    # carry on trying to save image 
end 

e quindi il codice di controllo sarebbe lungo le linee di:

begin 
    result = @item.save_image(params[:attachment][:file]) 
rescue Exception => ex 
    flash[:notice] = ex.message 
    redirect_to(new_item_url) and return 
end 
+1

che in realtà è un'idea molto migliore. Il motivo per cui mi stavo chiedendo se fosse una buona o cattiva pratica era perché potevano essere restituiti diversi tipi di dati. Non è un grosso problema dato che Ruby è flessibile in questo modo, ma dal punto di vista del codice pulito, comprensibile e gestibile mi ha semplicemente infastidito. – seaneshbaugh

+0

Mi piacciono decisamente le eccezioni. La prima soluzione che non mi piace. È un codice molto pulito, ma non mi piace il fatto che una funzione sia anche preoccupata del messaggio di errore che deve essere inviato all'utente. In una situazione I18n questo sarebbe completamente rovinato :) – nathanvda

+0

Questo è sicuramente un miglioramento rispetto ai metodi nella domanda, ma perdonatemi per non essere ancora soddisfatto. Il primo metodo ha due clunky variabili provenienti dalla chiamata e per verificare la riuscita servono più righe. Il secondo metodo metterebbe molte eccezioni e inizierà/riscuoterà tutta la mia app. Puzza. Voglio fare qualcosa del genere: render item.errors a meno che item.validate_x_y_z. È possibile? – TheJKFever

Problemi correlati