2012/03/05

case文を勘違いしていたのでメモ

case文ってifとかwhileとかと同じようなもんでしょ!と思ってたけど、ちゃんと調べたらなんか色々勘違いしていたのでメモ。

case文をif文で書き換えてみる

下記は普通のcase文。
ary配列の各要素の所属クラスによって条件分岐させている。

case version
ary = [1, "hoge", nil]

ary.each do |item|
  case item
  when String
    print item," is string\n"
  when Numeric
    print item," is numeric\n"
  else
    print item," is something\n"
  end
end

実行結果
$ ruby case_test.rb
1 is numeric
hoge is string
 is something
※3つ目の変数はnilなので、何も表示されない。

まずは素直にif文にしてみる

if version1
ary = [1, "hoge", nil]

ary.each do |item|
  if item == String
    print item," is string\n"
  elsif item == Numeric
    print item," is numeric\n"
  else
    print item," is something\n"
  end
end
ん?これでクラスの情報にアクセスしてくれるのかな?とりあえず実行してみる。
$ ruby case_test.rb
1 is something
hoge is something
 is something
あぁ。やっぱりだめ。「==」は値の等号の演算子だしね、、(「==」は類似のメソッドも判断できるらしい)全部somethingになってしまった。

こういう時は「===」という演算子を使うらしい。

調べてみると、、
「===」は左辺が数値や文字列の場合は「==」と同じ意味を持つが、左辺が正規表現の場合は「=~」と同じようにマッチ判定をする。また、左辺がクラスの場合は右辺がそのクラスのインスタンスかどうかを判定する。
なるほど。ということは下記もダメ。一応試してみる。

if version2
ary = [1, "hoge", nil]

ary.each do |item|
  if item === String                  # クラス名が右辺になっている
    print item," is string\n"
  elsif item === Numeric          # クラス名が右辺になっている
    print item," is numeric\n"
  else
    print item," is something\n"
  end
end
実行してみる。
$ ruby case_test.rb
1 is something
hoge is something
 is something
やっぱりだめだった。

左辺にクラス名を移動

ary = [1, "hoge", nil]

ary.each do |item|
  if String === item                    # クラス名を左辺にした
    print item," is string\n"
  elsif Numeric === item            # クラス名を左辺にした
    print item," is numeric\n"
  else
    print item," is something\n"
  end
end
実行してみる。
$ ruby case_test.rb
1 is numeric
hoge is string
 is something
やっといけた。
case文の挙動をちゃんと理解できていなかった。。一つ一つ根本を理解していく癖をつけたい。


0 件のコメント:

コメントを投稿