[Ruby]return,break,next それぞれの処理の終わらせ方


# 初めに

[paiza](https://paiza.jp/)で競プロみたいなことできるやん！！ってなってとりあえず朝の勉強初めはやる気出すために遊んでいるのですが。
その中でreturn等、処理を終わらせる記述の挙動についてわかってなかったな〜ってことがあったので書き留めておきます(正直まだ理解しきってはいない）

# 環境

Ruby 2.6.5

# 遭遇したこと

以下の様なコードを書いていました。(数値とかは問題の公表につながらない様書き換えています）

```ruby:test.rb
array = [1,2,3]
ans = []

array.each do |a|
  if a >= 1
    ans << a
    return
  end
end

p ans
```

簡略化した処理をしていますが、僕がやりたかったのは以下の様なことでした。

**配列の要素について条件を検証し、該当するものが見つかった時点でその値を空配列に入れ、繰り返し処理を終える**

上記のコードで言えば一番目の１の時点でifに該当しているので、ans = [1]となり処理が終わってくれれば良いのでした。

そして上記コードを実行した結果が以下の通り。

<img width="430" alt="スクリーンショット 2020-07-28 12.50.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619380/717fa775-82c4-1c7c-fe59-f53a3ed32a7b.png">


**何も反応しねえ。**

何もpされてこない訳です。
僕は最初これを、ansにaが入っていないから表示されていないと思い、returnでスコープが変わる・・・！？とか動揺してたんですが。
よく考えたらその場合でも p ansしたら　[]って感じで空の配列は表示されるはずなんですよね。

そう思って上記コードの最後に 「p array」と追記しても何も表示されなかったので、「ああーー処理が終わってんのか！」とたどり着くことができた訳です。

上記の様なケースに遭遇したため、処理を終わらせる方法について調べて出てきた３つについてまとめておこうと思います(return,break,next)



## returnについて

**returnはメソッドそのものを終わらせます**

上記が答えです。
それについては知っていたのですが、今回の場合defでメソッドを作っていた訳じゃないので以降の処理が終了するという状況が同じであると気付けませんでした。

ここ、正直あやふやですが、今回の様に何も定義しないでやってる場合は「そのプログラム全体を範囲として終了させる」ということでしょうか。

ちなみにメソッドを終わらせるとはどういうことか例を使ってもう少し説明すると

```ruby:test.rb
array = [1,2,3]
ans = []

def check
  array.each do |a|
    if a >= 1
      ans << a
      return
  end
puts "Hello"
end
```

上記の様なケースでcheckメソッドを実行した場合、returnが終わらせるのは**each処理ではなくcheck全てです。**
なので、returnでeachの処理が終わった後、puts "Hello"されるわけではありません、ということです。
何か処理の中で使われていても、その処理だけを終わらせるのではなく、メソッドそのものを終わらせるのがreturn ですよ、ということですね。


## breakについて

**breakはその繰り返し処理のみを終わらせます。**

今回の場合これが僕のやりたかったことですね。

```ruby:test.rb
array = [1,2,3]
ans = []

array.each do |a|
  if a >= 1
    ans << a
    break
  end
end

p ans

```

この様にreturnではなくbreakに書き換えてあげると
<img width="395" alt="スクリーンショット 2020-07-28 13.12.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619380/e98f6869-4542-d4ef-c16c-a267af1cc360.png">

望んでいた[1]がえられました。
条件に該当した時点で、each処理のみを終わらせてくれた、という期待していた挙動になっています。



## nextについて

**実行されてる処理内で、以降の処理を行わず終わらせますが、繰り返し処理自体は続きます**

ちょっとわかりづらいので、以下の様にコードを書き換えて実験して見ます。

```ruby:test.rb
array = [3,2,1]
ans = []
sum = 0

array.each do |a|
  if a >= 2
    ans << a
  end
  sum += 1
end

p sum
```

if内の条件をa >= 2にしたので、array[2]は１であるためそれのみ条件に非該当になります。
カウンター用にsumを用意しました。

これを実行すると以下の結果になります。

<img width="435" alt="スクリーンショット 2020-07-28 13.20.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619380/a48fc607-7c29-4faf-c725-aedb70dfdaca.png">

sum += 1はif外かつeach内の処理なので、ifに該当してようとしてなかろうと、要素の数だけ繰り替えされます。
今回は要素が3個あるので、「３」と出力されるわけです。

**これにnextを追記します。**

```ruby:test.rb
array = [3,2,1]
ans = []
sum = 0

array.each do |a|
  if a >= 2
    ans << a
    next
  end
  sum += 1
end

p sum
```

結果は以下の通りです。

<img width="409" alt="スクリーンショット 2020-07-28 13.22.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619380/b1aa7f98-0a21-1c74-8388-b9c3e10dc250.png">

ifに該当した場合、nextによって**以降の処理を無視します。**
なので3、2の場合はsum += 1が行われません。

ただし、**繰り返し処理自体は継続されます。**
なので、array[2]が１であり、ifに非該当であった場合はsum += 1が実行されており、結果として１が出力されているわけです。




# 終わりに

頭でわかってることをプログラムにやってもらう時の指示の出し方についてまだまだ知らないことが多いな〜という印象です。
機械語を理解するのは大事だなと思うわけで、半分趣味にはなってますがアルゴリズムの勉強もしたくてたまんないなという最近です。実際こういう気づきあるし笑

※かなりざっくりした理解で書いているので、間違い等あれば指摘いただけるとありがたいです。