Синтаксис Ruby: вырваться из блока "каждый.. сделать.."
Я разрабатываю приложение Ruby on Rails. Мой вопрос больше о синтаксисе Ruby.
У меня есть модельный класс с методом класса 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
Я хотел бы остановить/вырваться из блока each
один раз result
true (чтобы разбить блок each
, если car.name
совпадает с параметром name
один раз) И верните car
, которые вызывают результат true. Как прорваться в Ruby-код?
Ответы
Ответ 1
Вы можете разбить ключевое слово break
. Например
[1,2,3].each do |i|
puts i
break
end
выводит 1
. Или, если вы хотите прямо вернуть значение, используйте return
.
Поскольку вы обновили вопрос, вот код:
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
Хотя для этой цели вы также можете использовать Array#detect
или Array#any?
.
Ответ 2
Я предоставляю код плохой выборки. Я не могу найти или проверить что-то из базы данных. Мне просто нужен способ вырваться из "каждого" блока, если какое-то условие встречается один раз и возвращает этот "автомобиль", который вызывает истинное результат.
Тогда вам нужно:
def check(cars, car_name)
cars.detect { |car| car.name == car_name }
end
Если бы вы хотели узнать, есть ли какой-либо автомобиль с таким именем, вы должны использовать Enumerable#any?
. Как правило, используйте Enumerable#each
только для выполнения побочных эффектов, а не для выполнения логики.
Ответ 3
Вы можете использовать break
, но то, что вы пытаетесь сделать, можно сделать гораздо проще, например:
def self.check(name)
return false if self.find_by_name(name).nil?
return true
end
Это использует базу данных. Вы пытаетесь использовать Ruby в месте, где база данных может справиться с ней лучше.
Вы также можете использовать break
условный:
break if (car.name == name)
Ответ 4
вы можете использовать метод include?
.
def self.check(name)
cars.include? name
end
include?
возвращает true
, если name
присутствует в массиве cars
else, он возвращает false
.