!Mac OS X-10.15.7 !ruby-2.7.1p83$
if-elsif-else-end
お題
入力がうるう年(leap year)かどうかを表示するプログラムをかけ.
- うるう年は4で割り切れる数の年.ただし,
- 100で割り切れる年はうるう年でなく,
- 400で割り切れる年はうるう年.
- 2004, 1999, 1900, 2000で試せ.
- それぞれtrue, false, false, true
rubyのif
オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル
上記のサイトには以下のように書かれている
if 式 [then]
式 ...
[elsif 式 [then]
式 ... ]
...
[else
式 ... ]
end
上の表現で[]は省略可能箇所を示している.従って,最小で
if year%4==0 then
p 'not leap year'
end
とかで書ける.さらにthenは省略可能で,ifをつなげるのはelsif.ややこしい.
類題:2004年はleap year
> ruby check_leap_2004.rb 2004
とした時に
true
と出力するプログラムを作る
p year = ARGV[0].to_i
if year % 4 == 0
p true
end
上記のコードを実行すると
> ruby check_leap_2004.rb 2004
2004
true
となる.
類題:1999はfalse
p year = ARGV[0].to_i
if year%4 == 0
p true
else
p false
end
上記のコードを実行すると
> ruby check_leap_0.rb 1999
1999
false
ちゃんと出力されてる.
類題:1900年と2000年は?
p year = ARGV[0].to_i
if yeay % 400 == 0
p true
elsif year % 100 == 0
p false
elsif year % 4 == 0
p true
else
p false
end
条件増やすだけ.
array, each
テストの自動化
この後,さらにテストの内容が増えてくると,いちいち引数(ARGV[0])で全てチェックするのが面倒.そこで,テストを自動化するために配列にテストする年を入れて,loopで回す.
[2004,1999,1900,2000].each do |year|
p year
if yeay % 400 == 0
p true
elsif year % 100 == 0
p false
elsif year % 4 == 0
p true
else
p false
end
end
類題:refactoring_methodに
さっき書いたコードをメソッド化する
def leap?(year)
if year % 400 ==0
p true
elsif year % 100 ==0
p false
elsif year % 4 == 0
p true
else
p false
end
end
[2004,1999,1900,2000].each do |year|
p year
leap?(year)
end
case
お題:case
さっきのコードをcaseを使って短くする
caseの文法
先ほどのオブジェクト指向スクリプト言語 Ruby リファレンスマニュアルにcaseの解説がある以下は文法
case [式]
[when 式 [, 式] ...[, `*' 式] [then]
式..]..
[when `*' 式 [then]
式..]..
[else
式..]
end
解法
def leap?(year)
return case
when year % 400 ==0
true
when year % 100 ==0
false
when year % 4 ==0
true
else
false
end
end
[2004,1999,1900,2000].each do |year|
p year
leap?(year)
end
上記のコードを実行すると
> ruby leap_year.rb
2004
true
1999
false
1900
false
2000
true
もっと短いのあった…
def leap?(year)
case
when year % 400 ==0 ; return true
when year % 100 ==0 ; return false
when year % 4 ==0 ; return true
else ; return false
end
end
もっとすごいtdd
上の知識があると全く逆からのtddも可能.
def leap?(year)
case
when year == 2000 ; p true
when year == 1900 ; p false
when year == 2004 ; p true
else ; p false
end
end
より一般化して,
2000 -> % 400 == 0
とかにしても問題ない.
さらに,
def leap?(year)
return case
when year % 400 ==0 ; true
when year % 100 ==0 ; false
when year % 4 ==0 ; true
else ; false
end
end
とかもできる.
おまけ(三項演算子: ternary operator)
if_elseをもう少しスマートに書く方法があるらしい.
year = 1999
if year %4 ==0 then
return true
else
return false
end
return year%4 == 0 ? true : false
operation condition ? true_case : false_case
という文法でif-else-endを短く書くことが可能.
もう一つ,
return true if year %4 ==0
というようにelseがない場合は,ifを後ろに持っていくことが可能で,これも短くなる.unlessでも使えるらしい.実際に動かしてはない.
def leap?(year)
return (year%400 == 0) ? true :
(year%100 == 0) ? false :
(year%4 == 0) ? true : false
end
[2004, 1999, 1900, 2000].each do |year|
p year
p leap?(year)
end
と短くかけるんやって.
- source ~/grad_members_20f/members/okamoto0910/article/c7.org