2010-05-08 35 views
11

Tôi tự hỏi nếu viết các hàm như thế này được coi là dạng tốt hay xấu.Trả lại thông báo đúng hoặc lỗi trong Ruby

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

Và sau đó sử dụng nó, chúng ta làm một cái gì đó như thế này:

result = test(1) 

if result != true 
    puts result 
end 

result = test(2) 

if result != true 
    puts result 
end 

nào chỉ hiển thị thông báo lỗi cho các cuộc gọi thứ hai để kiểm tra. Tôi đang xem xét làm điều này bởi vì trong một dự án đường ray tôi đang làm việc bên trong mã điều khiển của mình, tôi thực hiện các cuộc gọi đến các phương thức của mô hình và nếu có điều gì sai, tôi muốn mô hình trả về thông báo lỗi cho bộ điều khiển và bộ điều khiển nhận thông báo lỗi đó và đặt nó trong flash và chuyển hướng. Kinda như thế này

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... 

Bằng cách đó tôi không xây dựng các thông báo lỗi trong bộ điều khiển, chỉ đơn thuần là đi qua chúng cùng, bởi vì tôi thực sự không muốn điều khiển được quan tâm với những gì các phương pháp save_image chính nó là chỉ giúp hay không nó hoạt động.

Điều đó có ý nghĩa với tôi, nhưng tôi tò mò muốn biết liệu đây có phải là cách viết hay hay hay. Hãy nhớ rằng tôi yêu cầu điều này theo nghĩa chung nhất liên quan đến ruby, nó chỉ xảy ra rằng tôi đang làm điều này trong một dự án đường ray, logic thực sự của bộ điều khiển thực sự không phải là mối quan tâm của tôi.

+1

của Ruby thường sử dụng 2 không gian để thụt, không 4. –

Trả lời

21

Tôi có thể nói rằng các phương thức trả về các loại khác nhau (ví dụ: boolean so với chuỗi so với số) trong các trường hợp khác nhau là thực tiễn không tốt.

Nếu bạn có một số loại phương pháp thử nghiệm mà muốn quay trở lại chi tiết về lý do tại sao các thử nghiệm đã không được thông qua sau đó bạn có thể trả về một cặp giá trị (một Array) như sau:

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

và sau đó viết phần mã điều khiển của bạn như:

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

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

Nếu bạn đang nói về một phương pháp save_image rằng sẽ thành công phần lớn thời gian, nhưng có thể thất bại và bạn muốn chỉ ra sự thất bại này và lý do thì tôi sẽ sử dụng exceptions ví dụ:

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

và sau đó mã điều khiển của bạn sẽ được dọc theo dòng:

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

Đó thực sự là một ý tưởng tốt hơn nhiều. Lý do tôi thậm chí còn tự hỏi liệu đây có phải là thực hành tốt hay xấu vì các loại dữ liệu khác nhau có thể được trả lại. Đó không phải là một vấn đề lớn vì Ruby linh hoạt như vậy, nhưng từ quan điểm của mã sạch, dễ hiểu, và duy trì nó chỉ làm tôi buồn phiền. – seaneshbaugh

+0

Tôi chắc chắn thích các ngoại lệ. Giải pháp đầu tiên tôi không thích. Đó là mã rất rõ ràng, nhưng tôi không thích thực tế là một hàm cũng quan tâm đến thông báo lỗi cần được gửi tới người dùng. Trong một tình huống I18n điều này sẽ hoàn toàn lộn xộn :) – nathanvda

+0

Điều này chắc chắn là một sự cải tiến từ các phương pháp trong câu hỏi, nhưng tha thứ cho tôi vì vẫn không hài lòng. Phương pháp đầu tiên có một biến 2 clunky đến từ cuộc gọi, và để kiểm tra sự thành công đòi hỏi nhiều dòng. Phương pháp thứ hai sẽ đặt rất nhiều ngoại lệ và bắt đầu/cứu tất cả trên ứng dụng của tôi. Mùi hôi. Tôi muốn làm một cái gì đó như thế này: render item.errors trừ khi item.validate_x_y_z. Điều đó có thể không? – TheJKFever

Các vấn đề liên quan