2011-12-14 22 views
36

Tôi đang phát triển một ứng dụng Ruby on Rails. Câu hỏi của tôi là thêm về cú pháp Ruby.Cú pháp Ruby: thoát ra từ 'mỗi .. do ..' khối

Tôi có một lớp mô hình với một phương pháp học self.check:

class Cars < ActiveRecord::Base 
    ... 
    def self.check(name) 
    self.all.each do |car| 
      #if result is true, break out from the each block, and return the car how to... 
      result = SOME_CONDITION_MEET?(car) #not related with database 
    end 

    puts "outside the each block." 
    end 
end 

Tôi muốn dừng/thoát ra khỏi each khối lần các resultđúng (đó là phá vỡ các khối each nếu car.name giống với thông số namesau khi) VÀ trả lại car gây ra kết quả đúng. Làm thế nào để thoát ra trong mã Ruby?

Trả lời

77

Bạn có thể ngắt bằng từ khóa break. Ví dụ:

[1,2,3].each do |i| 
    puts i 
    break 
end 

sẽ xuất 1. Hoặc nếu bạn muốn trả lại trực tiếp giá trị, hãy sử dụng return.

Vì bạn cập nhật các câu hỏi, đây mã:

class Car < ActiveRecord::Base 
    # … 

    def self.check(name) 
    self.all.each do |car| 
     return car if some_condition_met?(car) 
    end 

    puts "outside the each block." 
    end 
end 

Mặc dù bạn cũng có thể sử dụng Array#detect hoặc Array#any? cho mục đích đó.

1

Bạn có thể sử dụng break nhưng những gì bạn đang cố gắng làm có thể được thực hiện dễ dàng hơn nhiều, như thế này:

def self.check(name) 
    return false if self.find_by_name(name).nil? 
    return true 
end 

này sử dụng cơ sở dữ liệu. Bạn đang cố gắng sử dụng Ruby ở một nơi mà cơ sở dữ liệu có thể xử lý nó tốt hơn.

Bạn cũng có thể sử dụng break có điều kiện:

break if (car.name == name) 
+0

Tôi cung cấp mã mẫu không hợp lệ. Tôi không trực tiếp tìm hoặc kiểm tra thứ gì đó từ cơ sở dữ liệu. Tôi chỉ cần một cách để thoát ra khỏi khối "mỗi" nếu một số điều kiện đáp ứng một lần và trả lại 'chiếc xe' đó gây ra kết quả thực sự. – Mellon

+3

Vâng, bạn thậm chí có thể cải thiện điều này: 'def self.check (name); self.where (: name => name) .any ?; end' –

+0

đoạn đầu tiên có thể được viết: '!! self.find_by_name (name)'. – tokland

10

tôi cung cấp một mẫu mã xấu. Tôi không trực tiếp tìm hoặc kiểm tra một cái gì đó từ cơ sở dữ liệu. Tôi chỉ cần một cách để thoát ra khỏi khối "mỗi" nếu một số điều kiện đáp ứng một lần và trả lại 'chiếc xe' đó gây ra kết quả thực sự .

Sau đó, những gì bạn cần là:

def check(cars, car_name) 
    cars.detect { |car| car.name == car_name } 
end 

Nếu bạn muốn chỉ để biết nếu có bất kỳ chiếc xe với tên đó thì bạn muốn sử dụng Enumerable#any?. Theo quy tắc chung, chỉ sử dụng Enumerable#each để thực hiện các tác dụng phụ, không thực hiện logic.

+1

Tôi đã vinh dự đẩy bạn lên đến 10k! Chúc mừng. –

+0

@Mark: cảm ơn bạn rất nhiều! Bạn là hơn một nửa con đường của mình, chúc may mắn. – tokland

1

bạn có thể sử dụng phương thức include?.

def self.check(name) 
    cars.include? name 
end 

include? lợi nhuận true nếu name hiện diện trong cars mảng khác nó trả false.

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