2012-06-02 32 views
5

Tôi đang nghĩ đến các phương pháp kiểm soát dòng chảy tốt nhất. Tôi nên đi con đường nào?Kiểm soát luồng Ruby: ném một ngoại lệ, trả về 0 hoặc để nó thất bại?

1) Không kiểm tra bất cứ điều gì và để cho các chương trình thất bại (mã sạch, thông báo lỗi tự nhiên):

def self.fetch(feed_id) 
    feed = Feed.find(feed_id) 
    feed.fetch 
    end 

2) thất bại âm thầm bằng cách trả lại bằng không (tuy nhiên, "Mã sạch" nói, mà bạn không bao giờ phải trả lại null):

def self.fetch(feed_id) 
    return unless feed_id 
    feed = Feed.find(feed_id) 
    return unless feed 
    feed.fetch 
    end 

3) ném ngoại lệ (vì nó đặc biệt không để tìm một thức ăn bằng id):

def self.fetch(feed_id) 
    raise ArgumentError.new unless feed_id 
    feed = Feed.find(feed_id) 
    raise ArgumentError.new unless feed 
    feed.fetch 
    end 

Nói cách khác: tôi có nên sử dụng các điều kiện bảo vệ một cách tích cực, hay tốt hơn là dựa vào các phương thức Ruby/Rails và để chúng ném một ngoại lệ, nếu có điều gì xảy ra?

+1

nếu ActiveRecord này, 'tìm' sẽ phát ra nếu' id' không tồn tại, 'find_by_id' không thổi. – tokland

Trả lời

6

1) Không kiểm tra bất cứ điều gì và để cho các chương trình thất bại (mã sạch, thông báo lỗi tự nhiên):

Đó là ok "cho chương trình thất bại" với biết, trường hợp ngoại lệ thành văn bản, nhưng nhận được một khó chịu NoMethodError bởi vì bạn đã cố gắng sử dụng một đối tượng nil chỉ là bất cẩn. Trong ví dụ cụ thể của bạn, ActiveRecord#find đặt ra một tài liệu ActiveRecord::RecordNotFound ngoại lệ, vì vậy IMO đây là con đường để đi:

def self.fetch(feed_id) 
    Feed.find(feed_id).fetch 
end 

2) thất bại âm thầm bằng cách trả lại bằng không (tuy nhiên, "Mã sạch" nói rằng bạn nên không bao giờ trả về null):

Đó là một lời khuyên chung, nhưng Ruby được nhồi nhét với các phương thức trả về nil; và đó là ok (một lần nữa, miễn là nó được ghi lại), nó chỉ có nghĩa là "Không có gì" (và cho phép các mô hình rất nhỏ gọn something_that_can_be_nil || another_value). Trong trường hợp này tôi muốn viết nó ngắn gọn sử dụng Ick của maybe:

def self.fetch(feed_id) 
    Feed.find_by_id(feed_id).maybe.fetch 
end 

3) Ném ngoại lệ (vì nó đặc biệt không để tìm một thức ăn bởi id):

Có, nhưng sau đó cho phép phương thức nâng cao ngoại lệ nổi tiếng RecordNotFound, không phải là tùy chỉnh (trừ khi bạn muốn trừu tượng thực tế là bạn đang làm việc với AR, điều này có thể rất cồng kềnh).

2

Tôi nghĩ câu trả lời đúng là: nó phụ thuộc. Người dùng về mặt lý thuyết sẽ không bao giờ gặp phải bất kỳ thông báo lỗi nào từ khung công tác. Bạn phải luôn sẵn sàng để xử lý những trường hợp ngoại lệ này. Sự lựa chọn là tất cả của bạn (nếu nó không phải là một giao diện được sử dụng bên ngoài hoặc một cái gì đó).

Nếu bạn thực hiện tuyến đường đầu tiên, tôi nghĩ bạn nên nắm bắt truy vấn là bất kỳ nguồn cấp dữ liệu nào tồn tại với id đó, và sau đó cố gắng tìm nạp nó. Nếu nguồn cấp dữ liệu biến mất giữa hai, đó có thể là một vấn đề thực sự để báo cáo. Thứ ba là về cơ bản giống nhau. Bạn cần đảm bảo rằng bạn đã xử lý mọi tình huống và trong trường hợp ngoại lệ ném đó có thể giúp ngăn người dùng thấy lỗi.

Giải pháp thứ hai về cơ bản là điều này, nhưng với việc xử lý nội bộ. Với nil bạn báo hiệu rằng có một số vấn đề. Nó cũng phải được xử lý, báo cáo cho người dùng, hoặc một cái gì đó. Hạn chế là nếu bạn quên điều này, bạn có thể đánh lừa người dùng.

Tôi sẽ sử dụng phương pháp đầu tiên, với kiểm tra bổ sung trước để đảm bảo nó tồn tại. Nhưng nó phụ thuộc vào cách sử dụng.

+0

Có, nó phụ thuộc. Nếu nó là một lỗi nghiêm trọng mà các hoạt động phải thành công để giữ cho chương trình đang diễn ra, để cho nó thất bại hoặc ném một ngoại lệ. Nếu không, chỉ cần trả lại nil – texasbruce

2

Tôi sẽ sử dụng phiên bản sạch sẽ.

Nếu bạn không cung cấp feed_id cho phương pháp fetch, bản thân ruby ​​sẽ tăng ArgumentError: wrong number of arguments(0 for 1), vì vậy phần đầu tiên của số 3 là vô nghĩa.

Nếu bạn không cung cấp feed_id hợp lệ, khi đó cuộc gọi Feed.find(feed_id) sẽ tăng ngoại lệ khác, rất có thể là ActiveRecord::RecordNotFound với một thông báo nói rằng không thể tìm thấy nguồn cấp dữ liệu có ID được cung cấp hoặc không có ID nào được cung cấp (thông số feed_idnil), rằng nó không thể tìm thấy nguồn cấp dữ liệu không có ID. Tôi có thể cho rằng "nếu bạn gửi đầu vào không hợp lệ, nó có thể bị hỏng" và trong trường hợp đó, tôi nghĩ rằng ActiveRecord::RecordNotFound sẽ cung cấp cho bạn nhiều biết thêm thông tin về những gì đã xảy ra sai lầm hơn nếu bạn tăng một số ArgumentError.

Trả về giá trị rỗng hiếm khi là một điều tốt, vì điều đó sẽ không cho bạn biết điều gì thực sự đã xảy ra. Vì vậy, tôi cũng sẽ loại trừ # 2.

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