Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
15
Help us understand the problem. What is going on with this article?
@ktarow

Rubyでの例外処理内のreturnについて

More than 5 years have passed since last update.

例外処理内のreturnについて

Rubyの例外処理のreturnについてのメモ。

rescue節内でのreturn

まずはrescue節内でのreturnです。

class Return
  def test
    begin
      p "Begin"
      1/0
      return "return begin"
    rescue => ex
      p "Rescue"
      return "return rescue"
    ensure
      p ex
      p "Ensure"
    end
  end
end

obj = Return.new
p obj.test

実行結果がこちら

"Begin"
"Rescue"
#<ZeroDivisionError: divided by 0>
"Ensure"
"return rescue"

実行順として、
1. begin
2. rescue
3. ensure
4. return(rescue)
の流れになっており、rescue節内で処理が終了していることがわかります。

なお、begin~rescue~end内のスコープは同じなので、ensure節からrescue節の変数(オブジェクト)が見えています。

ensure節内でのreturn

次に、ensure節内でreturnです。

class Return
  def test
    begin
      p "Begin"
      1/0
      return "return begin"
    rescue => ex
      p "Rescue"
    ensure
      p ex
      p "Ensure"
      return "return ensure"
    end
  end
end

obj = Return.new
p obj.test

実行結果がこちら

"Begin"
"Rescue"
#<ZeroDivisionError: divided by 0>
"Ensure"
"return ensure"

実行順として、
1. begin
2. rescue
3. ensure
4. return(ensure)
の流れになっており、ensure節内で処理が終了していることがわかります。

rescue節内・ensure節内でのreturn

最後に、rescue節内・ensure節内でのreturnについてです。

class Return
  def test
    begin
      p "Begin"
      1/0
      return "return begin"
    rescue => ex
      p "Rescue"
      return "return rescue"
    ensure
      p ex
      p "Ensure"
      return "return ensure"
    end
  end
end

obj = Return.new
p obj.test

実行結果はこちら

"Begin"
"Rescue"
#<ZeroDivisionError: divided by 0>
"Ensure"
"return ensure"

実行順として、
1. begin
2. rescue
3. ensure
4. return(ensure)
の流れになっており、rescue内のreturnが実行されずにensure内のreturnで処理が終了していることがわかります。

また、rescue節を省いて例外を発生させない場合も考えて見ます。

class Return
  def test
    begin
      p "Begin"
      return "return begin"
    ensure
      p "Ensure"
      return "return ensure"
    end
  end
end

obj = Return.new
p obj.test

実行結果はこちら。

"Begin"
"Ensure"
"return ensure"

実行順としては、
1. begin
2. ensure
3. return(ensure)
となっており、begin節内のreturnは実行されず、ensure節内で処理が終了しています。

結論

上記からもわかるように、ensure内にreturn文を記述すると、その時点で処理が終了してしまうため、本来期待していた処理が行われません。
このため、ensure節内でのreturnは避けるべきです。

15
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
15
Help us understand the problem. What is going on with this article?