LoginSignup
0
0

More than 1 year has passed since last update.

return、 break、nextの違い

Last updated at Posted at 2022-05-16

「フォームから入力された値が不正だった場合にエラーメッセージを表示しよう」というメソッドの中で、「もし、このケースであればすぐに次の処理に移りたい」というときその行で「return」させてみたのですがそれだとメソッド自体から離脱してしまい次の行の処理ができなくなってしまったので別の方法を探してみました。

return

その時のコードはこのような形

def hoge
  error_messages = []
  CSV.parse(tsv_text, headers: true, col_sep: "\t") do |row|
    error_messages << "shop_id:#{row["shop_id"]}は存在しないIDです" if Shop.find_by(id: row["shop_id"]).blank?
    error_messages << "user_id:#{row["user_id"]}は存在しないIDです" if User.find_by(id: row["user_id"]).blank?
    error_messages << "comment_id:#{row["comment_id"]}は存在しないIDです" if Comment.find_by(id: row["comment_id"]).blank?
  end
  errors.add(:tsv_text, error_messages.join("<br/>").html_safe) if error_messages.present?
end

この時、「shop_idがなければその後の検証はしなくてもいい」という処理をしたかったので

def hoge
  error_messages = []
  CSV.parse(self.tsv_text, headers: true, col_sep: "\t") do |row|
    return error_messages << "shop_id:#{row["shop_id"]}は存在しないIDです" if Shop.find_by(id: row["shop_id"]).blank?
           error_messages << "user_id:#{row["user_id"]}は存在しないIDです" if User.find_by(id: row["user_id"]).blank?
           error_messages << "comment_id:#{row["comment_id"]}は存在しないIDです" if Comment.find_by(id: row["comment_id"]).blank?
  end
  errors.add(:tsv_text, error_messages.join("<br/>").html_safe) if error_messages.present?
end

としていました。しかしこれだとreturnした時にメソッド自体を離脱してしまい次の行の処理に移れなくなってしまうので何か違う方法で処理をしなければなりませんでした。

break

調べてみたところ途中で処理を止める方法はbreakとnextの二つあるようでした。結果的に後述するnextを使うことになるのですが、breakを使った場合どうなるのかも載せておきます。

def hoge
  error_messages = []
  CSV.parse(tsv_text, headers: true, col_sep: "\t") do |row|
    break error_messages << "shop_id:#{row["shop_id"]}は存在しないIDです" if Shop.find_by(id: row["shop_id"]).blank?
           error_messages << "user_id:#{row["user_id"]}は存在しないIDです" if User.find_by(id: row["user_id"]).blank?
           error_messages << "comment_id:#{row["comment_id"]}は存在しないIDです" if Comment.find_by(id: row["comment_id"]).blank?
  end
  # breakした場合直後にこの行が実行される
  errors.add(:tsv_text, error_messages.join("<br/>").html_safe) if error_messages.present?
end

breakの場合メソット自体は抜け出さないが「その繰り返し処理を全て終了する」という挙動になるようで、もし最初の行でbreakしてしまった場合、それ以降の行に対する検証をしてくれなくなってしまいます。

next

条件を満たす挙動をしてくれたのがこのnext。

def hoge
  error_messages = []
  CSV.parse(tsv_text, headers: true, col_sep: "\t") do |row|
    next error_messages << "shop_id:#{row["shop_id"]}は存在しないIDです" if Shop.find_by(id: row["shop_id"]).blank?
         error_messages << "user_id:#{row["user_id"]}は存在しないIDです" if User.find_by(id: row["user_id"]).blank?
         error_messages << "comment_id:#{row["comment_id"]}は存在しないIDです" if Comment.find_by(id: row["comment_id"]).blank?
  end
  errors.add(:tsv_text, error_messages.join("<br/>").html_safe) if error_messages.present?
end

nextの場合「次の繰り返しを終了する」という挙動になり、複数行の検証をできるようになりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0