2011-08-17 46 views
9

Tôi đã luôn luôn tìm kiếm một cái gì đó giống như Python trong khi/else struct trong Ruby để cải thiện mã của tôi.Ruby tương đương với Python cho/else

Điều đó có nghĩa là vòng lặp được thực hiện và nếu điều kiện trong vòng lặp không đúng bất kỳ lúc nào, thì nó sẽ trả về giá trị trong câu lệnh khác.

Trong ruby, tôi có thể làm như thế này:

if @items.empty? 
    "Empty" 
else 
    @items.each do |item| 
    item 
    end 
end 

Vậy là có một cách để cải thiện điều này?

Cảm ơn bạn trước.

Trả lời

3

Hm, bạn có thể viết nó như là một ternary:

@items.empty? ? 'Empty' : @items.each { |item| item } 

Bạn có thể muốn làm điều gì đó hữu ích hơn trong khối của bạn mặc dù, vì each được thực hiện đối với các tác dụng phụ của nó và trả về nhận ban đầu.

Cập nhật theo nhận xét của bạn: Tôi đoán gần nhất bạn có thể nhận được là một cái gì đó giống như

unless @items.empty? 
    @items.each { |item| p item } 
else 
'Empty' 
end 
+0

Tôi không thích nó chỉ trên một dòng. Điều đó không rõ ràng hơn. Những gì tôi muốn là một cái gì đó giống như trong khi/else/end. Có lẽ nó không thể nhưng tôi nghĩ rằng câu hỏi là giá trị nó. – Cydonia7

+1

Tôi đã tra cứu 'while/else' của Python ngay bây giờ, @Zabba là đúng, gần nhất có lẽ là' except..else' nếu bạn không thích dạng ternary. IMHO nó không có ý nghĩa để cố gắng dịch tất cả các cấu trúc từ một ngôn ngữ khác, nhưng YMMV. –

+0

Tôi không cố gắng dịch tất cả ngôn ngữ nhưng tôi nghĩ cấu trúc này trong Python thực sự hữu ích. Cảm ơn bạn đã trả lời :) – Cydonia7

24

Hãy nhớ rằng khối iterator trả về những gì bạn đưa vào nó, có thể được thử nghiệm để sử dụng tiếp.

if arr.each do |item| 
    item.some_action(some_arg) 
end.empty? 
    else_condition_here 
end 
+3

Điều này thật tuyệt vời. –

0

Một cách nhiều hơn hoặc ít chức năng:

empty_action = { true => proc{ "Empty"}, 
       false => proc{ |arr| arr.each { |item| item }} } 

empty_action[@items.empty?][@items] 
1

Kể từ khi chúng tôi đang trong Ruby, chúng ta hãy có niềm vui. Ruby có mạnh mẽ case xây dựng, có thể được sử dụng như thế này:

case items 
when -:empty? then "Empty" 
else items.each { |member| 
    # do something with each collection member 
    } 
end 

Nhưng để làm cho công việc mã trên, chúng ta phải sửa đổi các lớp bản địa Symbol đầu tiên. Sửa đổi các lớp bản địa là đặc sản của Ruby. Điều này cần phải được thực hiện chỉ một lần, thường là trong một thư viện (đá quý), và nó sẽ giúp bạn bao giờ sau. Trong trường hợp này, việc sửa đổi sẽ là:

class Symbol 
    def [email protected] 
    Object.new 
    .define_singleton_method :=== do |o| o.send self end 
    end 
end 

Mã này quá tải trừ unary (-) điều hành của Symbol lớp theo cách như vậy, mà nói -:sym trả về một con khỉ đối tượng trống mới vá với :=== phương pháp, được sử dụng đằng sau hậu trường bằng tuyên bố trường hợp.

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