web-dev-qa-db-ja.com

Ruby構文: 'each .. do ..'ブロックから抜け出す

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ブロックを停止/ブレークアウトしたいonce the resulttrue(それはeachブロックを壊すcar.namenameパラメーターと同じですonce)そして、trueの結果を引き起こすcarを返します。 Ruby code?

45
Mellon

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?をその目的に使用することもできます。

93
tbuehlmann

悪いサンプルコードを提供します。データベースから何かを直接見つけたりチェックしたりしません。ある条件が一度満たされた場合に「各」ブロックから抜け出し、真の結果をもたらす「車」を返す方法が必要です。

次に、必要なものは次のとおりです。

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

その名前の車があるかどうかだけを知りたい場合は、Enumerable#any?を使用します。経験則として、Enumerable#eachは、ロジックを実行するのではなく、副作用を実行するためにのみ使用します。

12
tokland

breakを使用できますが、次のように、やろうとしていることがはるかに簡単になります。

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

これはデータベースを使用します。データベースがより適切に処理できる場所でRubyを使用しようとしています。

break条件を使用することもできます:

break if (car.name == name)
1
davidb

include?メソッドを使用できます。

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

include?は、true配列にnameが存在する場合はcarsを返し、そうでない場合はfalseを返します。

1
Sayuj