aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-01-19 09:54:58 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-01-19 09:54:58 +0000
commit852500c963b991fe0e4175ecc9217215c1ad4094 (patch)
treed3cc8f557e0511a678db305e2716f1b815021fc3
parentad3c8a4ea0d63cd0461e6f5a6c8a1319c1fb529f (diff)
downloadruby-852500c963b991fe0e4175ecc9217215c1ad4094.tar.gz
parse.y: rescue/else/ensure in do-end
* parse.y (do_body): allow rescue/else/ensure inside do/end blocks. [Feature #12906] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57376 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--NEWS2
-rw-r--r--parse.y2
-rw-r--r--test/ruby/test_syntax.rb67
3 files changed, 70 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index daaacf94d9..71f57f21fc 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,8 @@ with all sufficient information, see the ChangeLog file or Redmine
* Top-level constant look-up is removed. [Feature #11547]
+* rescue/else/ensure are allowed inside do/end blocks. [Feature #12906]
+
=== Core classes updates (outstanding ones only)
=== Stdlib updates (outstanding ones only)
diff --git a/parse.y b/parse.y
index 07f14e5a6e..8f6b8ee800 100644
--- a/parse.y
+++ b/parse.y
@@ -3763,7 +3763,7 @@ brace_body : {$<vars>$ = dyna_push();}
do_body : {$<vars>$ = dyna_push();}
{$<val>$ = cmdarg_stack; CMDARG_SET(0);}
- opt_block_param compstmt
+ opt_block_param bodystmt
{
$$ = new_do_body($3, $4);
dyna_pop($<vars>1);
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index 0f927a328e..f4358d44a1 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -979,6 +979,73 @@ eom
assert_in_out_err(%w[-e redo], "", [], /^-e:1: /)
end
+ def test_rescue_do_end_raised
+ result = []
+ assert_raise(RuntimeError) do
+ eval("#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ tap do
+ result << :begin
+ raise "An exception occured!"
+ ensure
+ result << :ensure
+ end
+ end;
+ end
+ assert_equal([:begin, :ensure], result)
+ end
+
+ def test_rescue_do_end_rescued
+ result = []
+ assert_nothing_raised(RuntimeError) do
+ eval("#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ tap do
+ result << :begin
+ raise "An exception occured!"
+ rescue
+ result << :rescue
+ else
+ result << :else
+ ensure
+ result << :ensure
+ end
+ end;
+ end
+ assert_equal([:begin, :rescue, :ensure], result)
+ end
+
+ def test_rescue_do_end_no_raise
+ result = []
+ assert_nothing_raised(RuntimeError) do
+ eval("#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ tap do
+ result << :begin
+ rescue
+ result << :rescue
+ else
+ result << :else
+ ensure
+ result << :ensure
+ end
+ end;
+ end
+ assert_equal([:begin, :else, :ensure], result)
+ end
+
+ def test_rescue_do_end_ensure_result
+ result = eval("#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ proc do
+ :begin
+ ensure
+ :ensure
+ end.call
+ end;
+ assert_equal(:begin, result)
+ end
+
private
def not_label(x) @result = x; @not_label ||= nil end