Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
Ruby TIPS

Ruby TIPS

if修飾子/unless文/case文 ― ちょっと便利な条件分岐の構文とは?

2016年6月1日

Rubyには、if文のような一般的なもの以外にも、if修飾子/unless文/unless修飾子/case文といった便利な条件分岐の構文が用意されている。その基本的な使い方を解説。

ローグ・インターナショナル 羽山 博
  • このエントリーをはてなブックマークに追加

 Rubyでは、if文やcase文を使った一般的な条件分岐だけでなく、便利な条件分岐の構文がいくつか用意されている。今回は、他のプログラミング言語にはない、そういった便利な構文の使い方を見ていく。

if修飾子を利用する

 if文の一般的な書き方については後述のコラムを参照していただくこととして、if修飾子から見ていこう。if修飾子は、以下の例のように、式の後ろに書く。if修飾子に書かれた式がtrueのときだけ、前に書かれた式を実行する。

sample001.rb
i = 10
p i if $DEBUG
リスト1.1 デバッグ(DEBUG)モードのときだけ変数の値を出力する

$DEBUGの値がtrueのときにはp iを実行し、変数iの値を出力する。

 この書き方では、if文が前に出てこないので、制御構造に関する記述に注意をそがれることが緩和できる。それにより、処理そのもの(=どんな式を実行するか)が多少なりとも追いかけやすくなる。プログラムをデバッグモードで実行するには、rubyコマンドに-dオプションまたは--debugオプションを付けるとよい(実行例1.1)。

コンソール
$ ruby sample001.rb 
……何も表示されない……
$ ruby -d sample001.rb 
Exception `LoadError' at /usr/local/Cellar/ruby/2.2.3/lib/ruby/2.2.0/rubygems.rb:1231 - cannot load such file -- rubygems/defaults/ruby
10
$ 
実行例1.1 プログラムをデバッグモードで実行する

最初のrubyコマンドには-dを付けていないので、何も表示されない。2番目のrubyコマンドのように-dオプションを付けるとデバッグモードとなる。10という値が表示されていることが分かる。例外メッセージも表示されているが、これについては本文で説明する。

 なお、デバッグモードではプログラムの中で適切に対処された例外に関してもメッセージが表示されるので、実行例1.1のようなエラーメッセージが表示される(この例はOS X 10.11.4上のRuby2.2.3p173での実行例であり、異なる環境では他のメッセージが表示されることがある)。ちなみに、上のメッセージはrubygems.rbファイル内で対処されている例外に関するものなので、特に気にする必要はない。

 if修飾子の前に複数の式を書きたいときには、beginendで囲めばよい(リスト1.2)。

sample002.rb
i = 10
begin
  flg = true
  p i
end if $DEBUG
リスト1.2 beginとendで複数の式を囲む

$DEBUGの値がtrueのときには変数flgtrueを代入し、変数iの値を出力する

 蛇足だが、begin ... endも値を返す。返される値はbegin ... end内の最後の式なので、リスト1.2の例であれば、p iという式の値(つまり10)となる。

【コラム】if文の書き方

 条件分岐はプログラミングの基本的な知識なので、初歩から解説することは避け、ここでは、if文の書き方と例を簡単にまとめておくにとどめる。

 

書き方1: 条件式の値がtrueのとき、式を実行する

コード フローチャート
if 条件式 then
   
end
書き方1のフローチャート
書き方1のコードとフローチャート

 thenは省略しても構わない。また、式は複数書いてもいい。ただし、改行せずに全てを1行で書くときにはthenは省略できない。その場合、文は;で区切る必要がある

  • 例: 変数ageの値が60未満なら、変数rank"一般"を代入し、変数rate0.2を代入する。そうでなければ、何もせず次に進む
Ruby
if age < 60
    rank = "一般"
    rate = 0.2
end
書き方1:if文のコード例1(thenを省略)

 上の例と同じ処理を1行で書いた場合

Ruby
if age < 60 then rank = "一般"; rate = 0.2 end
書き方1:if文のコード例2(thenの省略は不可、文の区切り「;」が必要)

 

書き方2: 条件式がtrueのとき、式1を実行し、そうでない場合、式2を実行する

コード フローチャート
if 条件式 then
    1
else
    2
end
書き方2のフローチャート
書き方2のコードとフローチャート

 この場合も、式1や式2は複数書ける。

  • 例: 変数ageの値が60未満なら、変数rank"一般"を代入し、変数rate0.2を代入する。そうでなければ、変数rank"シニア"を代入し、変数rate0を代入する
Ruby
if age < 60
    rank = "一般"
    rate = 0.2
else
    rank = "シニア"
    rate = 0.0
end
書き方2:if文のコード例(elseを使用)

 式1や式2の部分にはさらにif文を書くこともできる(ifのネスト)。その場合は、書き方3のようにelseifをまとめて、elsifと書ける。また、文の最後の複数のendは1つにまとめられる

 

書き方3: 条件式1がtrueのとき、式1を実行し、そうでない場合で条件式2がtrueのとき、式2を実行する。elsif以下は複数書けるので、同様に評価していく。全ての条件に当てはまらない場合には式nを実行する

コード フローチャート
if 条件式1 then
    1
elsif 条件式2 then
    2
    :
else
    n
end
書き方3のフローチャート
書き方3のコードとフローチャート

このフローチャートでは、見やすくするため、書き方1や書き方2とはtruefalseの流れを逆に描いてあることに注意。

  • 例: 変数ageの値が20未満なら、変数rank"ジュニア"を代入し、さらに変数rate0.5を代入する。そうでない場合で、変数ageの値が60未満なら、変数rank"一般"を代入し、変数rate0.2を代入する。そうでなければ変数rank"シニア"を代入し、変数rate0を代入する
Ruby
if age < 20
    rank = "ジュニア"
    rate = 0.5
elsif age < 60
    rank = "一般"
    rate = 0.2
else
    rank = "シニア"
    rate = 0.0
end
書き方3:if文のコード例(elsifを使用)

unless文を利用する

 if文とは逆に、条件式がfalseのときに式を実行するには、unless文が使える。書き方は上のコラムでまとめたif文の書き方とほぼ同じで、ifの代わりにunlessを書くだけ。ただし、コラムの書き方3で示したelsifは使えない。これについても簡単な例を見ておこう。

sample003.rb
age = ARGV[0].to_i
unless age >= 60 then
 rank = "一般"
 rate = 0.2
else
 rank = "シニア"
 rate = 0.0
end
puts rank,rate
リスト1.3 unless文を使って、条件がfalseのときに実行する式を書く

unless文では、条件式がfalseのときにthen以下の式が実行される。条件式がtrueのときにはelse以下の式が実行される。この例では、変数ageの値が60以上でなければthen以下の式が実行され、そうでなければ(=変数ageの値が60以上であれば)、else以下の式が実行される。

 実行例は以下の通り。

コンソール
$ ruby sample003.rb 18
一般
0.2
$ ruby sample003.rb 60
シニア
0.0
$
実行例1.2 unless文を使ったプログラムの実行例

条件を満たしていないときに、then以下の文が実行されていることが分かる。

 通常は、if文だけでどのような条件分岐も表せるが、unless文を使った方が、条件が自然に表せる場合もある。ただし、上の例のようにelseまで指定する必要がある場合にはかえって分かりにくくなることの方が多いので、無理にunless文を使うよりは素直にif文を使った方がいい。

unless修飾子について

 なお、最初に述べたif修飾子と同様に、unless修飾子を書くこともできる。当然のことながら、その場合は、unlessの後に書いた式がfalseのときだけ、unlessの前の式が実行される。

case文の便利な使い方

 他のプログラミング言語では、case文に相当する文(C言語やJavaのswitch文など)は、ある変数の値によっていくつかに処理を分岐させるのに使うのが一般的である。Rubyでもそういった使い方はもちろんできるが、if文による多分岐と同様に、さまざまな条件による分岐もできる。一般的な使い方の例を見た後で、もう一つの使い方を見てみよう。

sample004.rb
area = ARGV[0].to_i
case area
  when 0..3 then
    area_name = "23区"
  when 4 then
    area_name = "多摩"
  else
    area_name = "その他"
end
puts area_name
リスト1.4 case文の一般的な使い方

caseの後に書いた式の値が、whenの後に書いた式の値に一致したとき、then以下の式が実行される。それまでの全ての条件に一致しない場合には、最後のelseの後の式が実行される。

 case文では、whenの後に範囲式(例えばリスト1.4の0..3)を書いてもいい。また、then以下の式を次の行に書く場合はthenを省略しても構わない。ただし、whenの後で改行せず、同じ行に実行したい式を書く場合はthenは省略できない。

 では、実行結果を見ながら、処理の流れを確認しておこう。

コンソール
$ ruby sample004.rb 0
23区
$ ruby sample004.rb 4
多摩
$ ruby sample004.rb 5
その他
実行例1.3 case文を使った多分岐処理の実行結果

コマンドライン引数の値は変数areaに代入される。変数areaの値が0123のいずれかのときには、when 0..3の場合に一致するので「23区」と表示される。4のときには「多摩」と表示され、それ以外のときは全て「その他」と表示される。

 Rubyのcase文では、caseの後の変数を省略すると、複数並ぶwhenの後の式が最初にtrueになる場合のthen以下の式が実行される。例を見てみよう。

 以下の例では、変数age(年齢)の値が10未満の場合には変数charge(料金)に0を代入し、変数stock(株式の保有数)の値が1000以上の場合は変数charge300を代入する。それ以外の場合は変数charge500を代入する。

sample005.rb
age = 20
stock = 2000
case
  when age < 10
    charge = 0
  when stock >= 1000
    charge = 300
  else
    charge = 500
end
puts charge
リスト1.5 case文を使ってさまざまな条件を調べる

caseの後に式を書かない場合は、さまざまな変数の値を利用した多分岐の処理が実現できる。if文をネストさせても同じことができるが、全ての条件式が同じカラムから書かれるので、条件式の並びが多少見やすくなる(ただし、elsifの「そうでないとき」という意味合いが意識しづらいかもしれない)。

 ここでは、変数ageの値と変数stockの値をプログラムの中で決めているので、汎用性に欠けるが、取りあえず実行して、動作を確認してみよう。

コンソール
$ ruby sample005.rb 
300
実行例1.4 さまざまな条件により多分岐させた場合の実行結果

この例では、変数ageの値が20、変数stockの値が2000なので、最初のage < 10falseになるが、次のstock >= 1000trueになるので、「300」という結果が表示される。変数ageや変数stockの値を変えて動作を確認してみよう。

 最後に補足だが、if文を使う場合でも、case文を使う場合でも、falsenil以外は全てtrueと見なされることにも注意しておく必要がある。

まとめ

 Rubyでは、if修飾子やunless修飾子で指定した条件がtrueのときにのみ、その前に指定した式を実行するといった書き方ができる。また、case文では1つの式の値による多分岐だけでなく、複数の式を使った多分岐の処理もできる。

処理対象:if文|if修飾子|unless文|unless修飾子|case文 カテゴリ:文法 > 制御構造 > 条件分岐

※以下では、本稿の前後を合わせて5回分(第6回~第10回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

Ruby TIPS
6. 桁区切り数値の記述と出力/文字列を逆順に/文字列の分割/文字列の各文字の利用 ― コーディングミスを防ぐには?(4)

初心者向けにRubyプログラミングの落とし穴を紹介。桁区切り指定で数値リテラルを記述する方法や、桁区切りの数値文字列を出力する方法、文字列を逆順に並べ替える方法、文字列を文字列で分割する方法、文字列を1文字ずつ扱う方法を説明する。

Ruby TIPS
7. 複素数(Complexクラス)を活用するには?

組み込みライブラリに含まれるComplexクラスによる基本的な複素数の取り扱い方、複素数の四則演算、平面上の点(ベクトル)の操作方法を説明する。

Ruby TIPS
8. 【現在、表示中】≫ if修飾子/unless文/case文 ― ちょっと便利な条件分岐の構文とは?

Rubyには、if文のような一般的なもの以外にも、if修飾子/unless文/unless修飾子/case文といった便利な条件分岐の構文が用意されている。その基本的な使い方を解説。

Ruby TIPS
9. while修飾子/until修飾子/while文/until文 ― ちょっと便利な繰り返し処理の構文とは?(1)

Rubyに用意されている繰り返し処理構文のうち、while文/until文の基本的な使い方と落とし穴を解説。また、while/until「修飾子」を使った簡潔な記述方法にも言及する。

Ruby TIPS
10. for文 ― ちょっと便利な繰り返し処理の構文とは?(2)

Rubyに用意されている繰り返し処理の構文のうち、for文の基本的な使い方と配列と組み合わせた利用例を解説。範囲や配列を利用して一定の回数だけ繰り返して文を実行する方法や、配列全体を処理する方法を紹介する。

サイトからのお知らせ

Twitterでつぶやこう!