経緯
- Rubyを学び始めた頃のコードを直しているのですが、Javaエンジニアだったためかメソッド内に無駄なreturn文が多いです。
- 直す最中に表題の件について気になったので、
Rails c
を使って試し、またRailsのビューから呼ばれた時はどうなるのかについても試してみました。
修正前
- ひどい書き方ですね。。。
game.rb
def get_msg
msg = ""
if self.gameset_flag
if get_sum_top == get_sum_bottom #同クラス内の別のインスタンスメソッドを呼んでいます
msg = "(引き分け)"
elsif !self.top6
msg = "(5回コールド)"
elsif !self.top7
msg = "(6回コールド)"
elsif !self.top8
msg = "(7回コールド)"
elsif !self.top9
msg = "(8回コールド)"
end
end
return msg
end
修正後
- このメソッドをビューから呼んだ時に、どのif文にも入らなかった場合は、ちゃんと空文字で画面表示できるのか気になっていました。
game.rb
def get_msg
if self.gameset_flag
if get_sum_top == get_sum_bottom #同クラス内の別のインスタンスメソッドを呼んでいます
"(引き分け)"
elsif !self.top6
"(5回コールド)"
elsif !self.top7
"(6回コールド)"
elsif !self.top8
"(7回コールド)"
elsif !self.top9
"(8回コールド)"
end
end
end
Rails c
で動かしてみる
- コード修正は今回の主旨ではないため、修正後のコードのみで試します。
irb(main):001:0> game = Game.new
(出力省略)
irb(main):002:0> game.get_sum_top
=> 0
irb(main):003:0> game.get_sum_bottom
=> 0
irb(main):004:0> game.gameset_flag = false
=> false
irb(main):005:0> game.get_msg
=> nil
irb(main):006:0> game.gameset_flag = true
=> true
irb(main):007:0> game.get_msg
=> "(引き分け)"
どのif文にも入らない場合は、最初のif文の条件式が最後に評価されたことになります。-
つまりself.gameset_flag
はnil
ということでnil
が返って来ているのがわかります。
→(2019/04/17追記)上記2行誤りでした。申し訳ございません。
(2019/04/17追記)
正しくは、Rubyでは以下のルールがあり、
- if文自体も「一つの式」とみなされること。つまり値を返すということ
- 「if文の中に入らなかった かつ else節もない場合」はそのif文はnilを返すこと
その結果、irb(main):005:0> game.get_msg
のとき、 get_msg
メソッドでは以下のことが成り立っていました。
- if文には入らない、かつelse節も無いため、if文は
nil
を返す -
nil
を返したif文自体がget_msg
メソッドで「最後に評価された式」とされる -
get_msg
メソッドがnil
を返す
コメントにてご指摘をくださった@scivolaさん、ご教授ありがとうございました。
画面表示はどうなる
- 実際の画面キャプチャは貼れないのですが、結論としては問題ありませんでした(空文字がreturnされていた頃と表示に変化なし)。
- つまり、修正前のコードのように、どのif文にも入らなかった時のための変数の初期化は不要ということになります(もちろん設計上空文字を返却する必要がある場合は、メソッドの最終行に空文字を書いて、空文字が最後に評価されるようにすると良いと思います)。