◆当サイトで人気のプログラミング教室のおすすめランキングはこちら!
プログラミングは独学では非効率で、時間を無駄にするリスクがあります。効率的なカリキュラムで学べるスクールを受講しましょう。

DMM WEBCAMP【マンツーマンサポート】1ヶ月短期集中でプログラミングを学ぶスクール
1ヶ月通い放題・メンター常駐の教室環境でプログラミングを学びたい方!
TechAcademyオンラインで開講しているプログラミングスクール
オンラインでどこでも学べる!/教室に行くのが忙しい人でも安心!
TECH::CAMP教養としてのITスキルを学べるスクール
Webデザイン/AI(人工知能)/IOS/Androidアプリ制作/VRを学びたい方!
DMM WEBCAMP PRO転職保証付き!エンジニアとして転職したい人におすすめ!
未経験からプロのエンジニアへ3ヶ月で転職する為のスクールです!
1月生募集中!当社人気の転職保証コース
プログラミング学習から転職成功まで導く、当社人気のDMM WEBCAMP PROコース。
12月生は満員となっております。1月生募集に向け、お早めの申込みをオススメします。
プログラミング未経験でもエンジニア転職を絶対成功させたい
スキルを身に着けて人生を自ら切り開きたい
上記にあてはまる方は、ぜひご検討ください!
※プログラミングを学んでみたいけど、時間がなくて全文の記事が読めない!という方は、WebCampの無料説明会(毎日開催)に参加してみてください!

Ruby繰り返し処理 break next redo

forやwhile、eachなど、Rubyにはいくつもの繰り返し処理を表現する方法があります。

それらはそれぞれ、使用に適したシーンがあり、きちんと使い分けることで、プログラムの可読性(読みやすさ)を上げて不具合を防ぎ、再利用もしやすくできます。

これらの繰り返し処理を制御するのに使うのが、break,next,redoです。

break,next,redoを使うことで、繰り返しを中断したり、処理を飛ばしたり、やり直したりすることができます。

そんな、break,next,redoについて、詳しく解説していきましょう。

break,next,redoとは?

繰り返しを制御するbreak,next,redoについては、「【Ruby入門説明書】繰り返し、forについて解説」でも紹介していますが、ここではより詳しい解説を行います。

まずは、break,next,redoのそれぞれについて紹介しましょう。

なお、具体的に以下のプログラムを動かすことで、理解が早まると思います。

break01.rb

i = 10

while i > 0
  j = i
  i -= 1
#  next if j % 5 == 0  # (2) jが5で割り切れたら、ここ以降の処理はしない
  while j > 0
    j -= 1
#    break if j < 5    # (1) jが5よりも小さければ、繰り返しを抜ける
#    redo if j > 7     # (3) jが7よりも大きければ、以降の処理は無視して繰り返しをやり直す
    print("()")
  end
  print("--")
  puts(i+1)
end

whileの中にwhileが入っていて、一見ややこしそうなプログラムですが、外のwhileでカウントアップ、内側のwhileではカウントダウンしながら、「()」を表示するプログラムです。

この状態では、break,next,redoの処理はすべてコメントアウトされていますので、すべての繰り返し処理を行い、以下のような結果になります。

()()()()()()()()()()--10
()()()()()()()()()--9
()()()()()()()()--8
()()()()()()()--7
()()()()()()--6
()()()()()--5
()()()()--4
()()()--3
()()--2
()--1

この結果が、break,next,redoの処理を有効にすることによってどう変わるのか、想像しながら読み進めていただければと思います。

break

繰り返し処理の中には、集計のように決められた回数必ず処理しなければいけない場合と、検索のように結果が出たらそこで止めても良い場合があります。

後者の場合に利用するのが、breakです。

Rubyは、繰り返し処理の中でbreakに到達すると、ただちに繰り返し処理の次のステップへと処理を移します。

その結果、繰り返し処理は終了してしまうわけです。

他言語の中には、case〜whenの処理内でbreakが必須なものもあります。しかし、Rubyでは不要(むしろ、繰り返し処理の外でbreakがあるとエラーとなる)ですので、気を付けましょう。

メリット

不要な繰り返し処理を行わないことで、処理の効率が上げり、プログラムのレスポンスが良くなります。

breakがなければプログラムしにくいロジックもあります。

デメリット

繰り返し処理の中で変化していた変数などは、breakの直後の状態になっています。ほとんどの場合は問題ないとは思いますが、もし後処理が必要なもの(例えばファイル操作では、開いたファイルを閉じなければいけません)については、breakすることで後処理がされないことになる可能性がありますので、注意が必要です。

動かしてみる

break01.rbの(1)のコメントを外して動かしてみましょう。

(1)は内側のwhile の中で、カウントダウンされているjが5よりも小さくなると、繰り返し処理を抜けます。つまり、jが5よりも小さくなると、「()」が表示されないわけです。

どう動くのか、想像してから動かしてみましょう。

(結果)

()()()()()--10
()()()()--9
()()()--8
()()--7
()--6
--5
--4
--3
--2
--1

コツコツ独学×スクールで実践。未経験からエンジニアに転職!【WebCamp卒業生インタビュー】

next

繰り返し処理の中には、どれだけ長い処理があってもかまいません。そのため、プログラムによっては繰り返し処理の中で様々なことを行います。

そうすることで、あちこちで繰り返すことを避け、プログラム全体の効率を上げているわけです。

しかし、特定の条件の場合等には、それ以降の処理を行わずに繰り返しの先頭へ移行して、次の繰り返しへ進みたい場合もあるでしょう。

そんなときに利用するのが、nextです。

Rubyは、繰り返し処理の中でnextに到達すると、以降の処理をすべて飛ばして、繰り返し処理の先頭へ移行し、次の繰り返し処理を開始します。

つまり、繰り返し処理を次(next)に進めるわけです。

他の言語では、同様の処理を行うのにcontinueというステートメントを利用するものがあります。

メリット

nextのメリットは、処理を一気に飛ばしてしまえることです。

例えば、配列に様々なオブジェクトが格納されている場合、特定のオブジェクトの場合だけ処理をするプログラムを作成し、そのオブジェクト以外はnextで処理を飛ばしてしまえば、余計な処理を作成する必要がありません。

なにより、余計な処理が行われませんので効率も良いでしょう。

デメリット

breakと同様に、後処理を忘れないようにしなければいけません。

ただし、breakと違って繰り返し処理は行います。つまり、何度も後処理忘れを繰り返してしまうことになりますので、メモリ不足など原因特定の難しい不具合の元になる可能性があります。

動かしてみる

break01.rbの(2)のコメントを外して動かしてみましょう。

(2)は外側のwhile の中で、内側のwhileのカウンタであるjが5で割り切れると、以降の処理を無視します。

実際に動かして結果を確認してから、プログラムコードを見直してみるのも、良い勉強になります。

(結果)

()()()()()()()()()--9
()()()()()()()()--8
()()()()()()()--7
()()()()()()--6
()()()()--4
()()()--3
()()--2
()--1

redo

繰り返し処理を続けている中で、すべてをリセットしてやり直すしかない状況になる場合もわずかながらに存在します。(通信のネットワークエラーなどは、最初からやり直すことでスムーズに進むことがあります)

そんな場合に、繰り返し処理をやり直すことができるredoが便利です。

繰り返し処理の中でredoがあると、Rubyは繰り返し処理を中断して、最初からやり直します。

メリット

繰り返し処理を作る上で、最初からやり直すシーンはそれほどないかもしれませんが、やり直す処理をredoなしで作ろうとすると、別の繰り返し処理を必要とするなど、複雑なプログラムになることでしょう。それをbreakやnextのようにすっきりと記載できるのは、大きなメリットです。

デメリット

繰り返し処理を最初からやり直すといっても、後処理が必要なものまでなかったことにはなりませんので、breakやnextと同じ後処理忘れには気を付けなければいけません。

また、それに加えて、やり直す条件が必ず成り立たなくなるようにするか、breakなどで繰り返し処理を中断する処理を組み込んでおかなければ、簡単に無限ループになってしまいますので、安易な使用はたいへん危険です。

動かしてみる

break01.rbの(3)のコメントを外して動かしてみましょう。

(3)は内側のwhile の中で、カウントダウンしているjが7よりも大きい間、繰り返し処理を一旦やめてやり直しています。つまり、jが7になるまで、redoの後ろの処理は行われません。

どんな図形が表示されるでしょうか?

(結果)

()()()()()()()()--10
()()()()()()()()--9
()()()()()()()()--8
()()()()()()()--7
()()()()()()--6
()()()()()--5
()()()()--4
()()()--3
()()--2
()--1

break,next,redoの違い

break01.rbで実際の動作を確認しましたが、break,next,redoは、それぞれ繰り返しの制御の仕方が違っています。

改めて、break,next,redoの違いをまとめると、以下のようになります。

・breakは、繰り返し処理を中断する
・nextは、以降の処理をスキップして、繰り返し処理を継続する
・redoは、繰り返し処理を中断して、最初からやり直す

この違いを理解しておけば、繰り返しの処理を柔軟に効率よく作っていくことができますので、憶えておきましょう。

“未経験”でもたった1ヶ月で営業からエンジニアとして転職!『WebCamp』受講者インタビュー

break,next,redoの使いどころ

break,next,redoの動きを理解したところで、どう使うかというのが分からなければ、意味がありません。

特にこの3つは繰り返し処理の流れを大きく変え、ときには無限ループまでも引き起こしてしまうような力を持っています。

そのため、基本的な使いどころくらいは理解した上で使っていきたいものです。

whileやunlessには、なくてはならない相棒?

breakやnext,redoは、繰り返し処理の処理を行うかどうかを制御するのに使います。

そのため、あらかじめ処理の回数が決まっているforやeachでの使用は、限定的になるかもしれません。(もちろん、プログラムの効率化のために余計な処理を省くことができますので、とても有意義です)

つまり、breakやnext,redoの真価が発揮されるのは、whileやunlessなどの「回数が決まっていない」繰り返し処理になるわけです。

whileやunlessは、もちろん繰り返しが終わる条件を設定できます。しかし、あまり複雑な条件を設定するのは可読性を犠牲にすることになりますので、推奨できません。

そのため、最低限の終了条件はwhileやunlessで設定し、その他の条件で繰り返し処理を制御するのにbreakやnextを利用するわけです。

普通のプログラムでは必須

実際にユーザーが使用するプログラムで、処理が完了すると終了するようなプログラムは稀です。

むしろ、常に動いており何らかの条件が成立したら(終了ボタンが押されるなど)終了する、というものが一般的でしょう。

そのため、多くのプログラムで敢えて「無限ループ」が実装されています。

そして、その無限ループの中で、終了ややり直しなどを行うために必要なのが、breakやnext、redoなのです。
(※breakやnextがなければ、今のプログラムの形を記載するのは、とても面倒で読みにくいものになることでしょう)

つまり、無限ループから抜けたり、無限ループ内での流れを変えたりするための道具として、breakやnextを使うわけです。

break,next,redoは、ifと組み合わせて

繰り返し処理の中でbreak,next,redoが現れると、それ以降に書かれている処理は無視されます。

つまり、これらが何の条件もなく現れることはありえないと考えても間違いではないでしょう。

そのため、break,next,redoは、ifなどの条件分岐と組み合わせ、一定の条件が成り立った(成り立たなかった)場合のみ実行されるように作るのが一般的です。

(※break01.rbでも、breakやnext、redoはifとセットで使用しています)

引数を渡すと、繰り返しの戻り値が変わる?

ここまでは、break,next,redoを実際にプログラムで使うに当たって必要な、動きや使い方の説明をしてきました。

ここからは、もっとRubyらしい理論的な部分を説明しましょう。

引数と戻り値

ここからの説明のために、「引数」と「戻り値」について最初に解説しておきます。

まず、「引数」というのは、処理に渡すデータ(値や文字列など)のことです。
そして、「戻り値」というのは、処理結果として返ってくるデータのことです。

例えば、以下のプログラムでは、putsにiとstr、"test"、lenという引数を渡しています。また、lenはstrのlengthメソッドからの戻り値(strの文字列の長さ)を受け取っています。

i = 10
str = "TEST"
len = str.length()

puts(i, str, "test", len)

breakに引数を渡せる

そもそも、Rubyではforにも戻り値があります。

これは、他の言語からRubyに移行した人にはとても不自然に感じることかもしれませんが、Rubyではごく自然なことです。

具体的に見ていきましょう。

break02-1.rb

ret = for i in 0..9
  result = (i * i).to_s + " "
  print(result)
end
puts
print(ret)

(結果)

0 1 4 9 16 25 36 49 64 81
0..9

このように、forの戻り値をretで受け取ることに対して何のエラーも発生せず、最後には内容を表示することもできています。
(※forの戻り値は繰り返しの元になるオブジェクトがそのまま返されます)

じつは、breakはこの繰り返し処理の戻り値を操作することができるのです。

戻り値の操作といってもよく分からないと思いますので、break02-1.rbにbreakを使って途中で繰り返しを抜けるようにしてみましょう。

break02-2.rb

ret = for i in 0..9
  result = (i * i).to_s + " "
  if i * i > 50
    break
  end
  print(result)
end
puts
print(ret)

(結果)

0 1 4 9 16 25 36 49 

結果の1行目で、50の直前まで出力されていますので、breakが動いて繰り返し処理が完了していることが分かると思います。
ポイントは、2行目が空白になっているところです。

これは、じつはbreakが返している値です。

もっと分かりやすくするために、breakに引数を渡してみます。

break02-3.rb

ret = for i in 0..9
  result = (i * i).to_s + " "
  if i * i > 50
    break("break!")
  end
  print(result)
end
puts
print(ret)

(結果)

0 1 4 9 16 25 36 49
break!

そうです。breakに渡している引数が、そのまま繰り返し処理の戻り値に上書きされているのです。

つまり、break02-2.rbでは、breakに引数が渡されていないから、繰り返し処理の戻り値も何も表示されなかったわけです。

これは、forだけではなくeachでも使えますので、繰り返し処理を1つの処理ブロックとしてプログラムを作ることができますので、利便性の高い機能といえます。

じつはnextにも引数を渡せる

breakと同様に、nextにも引数を渡すことができます。

nextの引数も、基本的にはbreakと同じで、戻り値に影響します。しかし、breakが繰り返し処理終了時の戻り値であるのに対し、nextの場合は繰り返し処理の1周終了時の戻り値になるところが大きく違います。

そのため、break02のようにfor文では意味をなしません。

引数付きのnextがその真価を発揮する代表的な繰り返し処理は、繰り返しごとの処理結果を配列として戻り値を返すmapメソッドです。

例えば、以下のように3で割り切れる場合は処理を飛ばしてしまう場合を考えましょう。

break03-1.rb

list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

ret = list.map do |num|
  next if num % 3 == 0
  num * num
end
print(ret)

(結果)

[1, 4, nil, 16, 25, nil, 49, 64, nil, 100]

結果のように、3で割り切れる要素は処理をしていませんので、無効値(nil)が格納されてしまっています。

こういった場合に、引数付きnextが役立ちます。

処理をしませんので、引数付きnextを使って、0を格納するようにしましょう。

break03-2.rb

list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

ret = list.map do |num|
  next 0 if num % 3 == 0
  num * num
end
print(ret)

(結果)

[1, 4, 0, 16, 25, 0, 49, 64, 0, 100]

先ほどnilだった場所に0が格納されました。これで、処理がぐっと楽になると思います。

他言語のcontinueと違って、繰り返し処理を中断しているわけではない

以上のように、Rubyのbreakやnextは、「戻り値を設定する」という機能を持っています。

これはつまり、多くのサイトや書籍で他言語のbreakやcontinueと同じようなものと説明されていますが、じつは内部的にまったく違っているということを理解しておきましょう。

他言語のbreakやcontinueは、本当に処理の流れを書き換えている場合がほとんどです。(「次はどの命令を実行するか」を示している値を直接書き換えています)

しかし、Rubyのbreakやnextは、「戻り値を返している=処理を完了の機能を実行している」ということになります。

この理解があれば、breakやnextに引数があることに違和感を覚えることはなくなるでしょう。

もちろん、プログラムを作る上で、その動きはほぼ同じですので、多くのサイトや書籍が噓を伝えているわけではありません。

“未経験”でもたった1ヶ月で営業からエンジニアとして転職!『WebCamp』受講者インタビュー

breakpointで検索してきた人へ

最後に、本稿を訪れる人の中の「breakpoint」で検索してきた人へ向けての補足を書いておきます。

本稿で説明しているbreakは、あくまでも繰り返し処理を終了するbreakメソッドについてです。

「breakpoint」とは、まったく違うものです。

「breakpoint」というのは、ほぼすべてのデバッガにある機能で、デバッグ時にプログラムを一時停止するポイントのことを意味します。

この「breakpoint」が設定された状態で、デバッガ上でプログラムを動かすと、プログラムがbreakpointに達した瞬間にプログラムは停止し、そのときの変数の状態などを確認、変更することができるようになります。

この機能はプログラムの動きを解析する上でとても便利な機能ですので、ぜひ積極的に使うことをおすすめします。

なお、「【Ruby入門説明書】stepについて解説」で紹介しているRuby標準のデバッガにも搭載されており、紹介していますので、ご参照いただけますと幸いです。

まとめ

長くなってしまいましたが、break,next,redoの解説は以上です。

break,next,redoは、機能的にあまり目立つことはなく、簡単に説明されていることが多いですが、うまく使えばプログラムの効率を上げ、プログラムコードをすっきりと見やすくしてくれる効果があります。

その反面、使い方を誤ると意図しない無限ループに陥ることもある両刃の剣といえるものです。

もちろん、深く追求すればもっと詳しく書けますが、文章では長くなりますので、これ以上のことを知りたければ、プログラム教室などで直接講師に聞いてみることをおすすめします。こういった目立たないTIPSは、プログラムをかじったことのある人は大好物ですので、いろいろと教えてくれることでしょう。

・breakは、繰り返し処理を中断する
・nextは、以降の処理をスキップして、繰り返し処理を継続する
・redoは、繰り返し処理を中断して、最初からやり直す
・無限ループを作ってしまう恐れがあるので、しっかり設計すること
・無限ループを抜ける仕組みには、breakが必須
・「引数」は、処理に渡すデータ(値や文字列など)のこと
・「戻り値」は、処理結果として返ってくるデータのこと
・breakの引数は、繰り返し処理の戻り値になる
・nextの引数は、繰り返し処理1周分の戻り値になる
・breakpointはプログラムを一時停止するデバッガの機能およびそのポイントのこと

DMM WEBCAMP ONLINE/プログラミングコースについて

WEBCAMPでは、「どこでも学べる」オンラインコースを開講しています。

初心者・未経験の方でもわずか1ヶ月でプログラミングの基礎を学び、アプリケーション開発をすることができます。

DMM WEBCAMP ONLINEが選ばれる3つの理由

1.学習の仕方がわからなくても安心!初心者に寄り添った学習カリキュラム

これから学習を始める初心者の方や、独学で挫折してしまった方に向けて、アプリケーション作成をゴールとする一気通貫したカリキュラムを提供しています。2500名を輩出しているWebCampだからこその教室でのリアルな受講生の声を反映し、オンラインコースでも初心者に寄り添った学習体験をご提供いたします。

2.つまずいたらすぐ解決!プロのエンジニアに質問し放題

プログラミング学習で挫折する理由の多くは「つまずいた時に聞ける人がいない」ことです。オンラインコースでは、現役エンジニアやプロ講師に、すぐにチャットでの質問が可能です。つまずきをすぐに解消できるので、挫折せずに学習を継続することができます

3.1ヶ月間で終わらなくても大丈夫!カリキュラムは"卒業後"も"無料"で利用可能

受講したいけど、仕事が急に忙しくなるかもしれないから受講するか迷っている・・・そんな方も多いのではないでしょうか?ご安心ください。カリキュラムは期間終了後も「無料」で使うことができます。また、しっかり学習時間を確保した方も、振り返って学習することでプログラミングスキルがご自身に馴染んできます。

▼まずは無料でWEBデザインのカリキュラムを体験しよう!

【インタビュー】1ヶ月でRubyをゼロから学び、Webエンジニアとして転職!

ブラジルから帰国し技術をつけようとRubyエンジニアを目指してWebCampでRubyを学び、見事Webエンジニアとして転職を果たした田中さんにお話を伺いました。

Rubyの学習がしたい。基礎をしっかりと理解したい

転職のサポートがほしい

と考えている方はぜひお読み下さい。

【WebCamp卒業生インタビュー】1ヶ月でRubyをゼロから学び、Webエンジニアとして転職!

おすすめの記事