diff --git a/doc/syntax/literals.rdoc b/doc/syntax/literals.rdoc index f5b9738..3337272 100644 --- a/doc/syntax/literals.rdoc +++ b/doc/syntax/literals.rdoc @@ -221,13 +221,21 @@ quotes: p expected_result # prints: "One plus one is \#{1 + 1}\n" The identifier may also be surrounded with double quotes (which is the same as -no quotes) or with backticks. When surrounded by backticks the HEREDOC -behaves like Kernel#`: +no quotes), with backticks or with forward slashes. When surrounded by +backticks the HEREDOC behaves like the heredoc text was surrounded by backticks puts <<-`HEREDOC` cat #{__FILE__} HEREDOC +When surrounded by forward slashes the HEREDOC creates regular expresion and +can be followed by switches. + + "0123a bob".match <<-/HEREDOC/x +[0-9]*[a-z] # search for 0 or more digits followed by one lowercase letter and the word 'bob' +\sbob + HEREDOC + To call a method on a heredoc place it after the opening identifier: expected_result = <<-EXPECTED.chomp diff --git a/parse.y b/parse.y index 7a14941..8d3051a 100644 --- a/parse.y +++ b/parse.y @@ -6430,6 +6430,11 @@ parser_parse_string(struct parser_params *parser, NODE *quote) rb_encoding *enc = current_enc; if (func == -1) return tSTRING_END; + if (func == -2) { + set_yylval_num(regx_options()); + dispatch_scan_event(tREGEXP_END); + return tREGEXP_END; + } c = nextc(); if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) { do {c = nextc();} while (ISSPACE(c)); @@ -6501,7 +6506,9 @@ parser_heredoc_identifier(struct parser_params *parser) case '"': func |= str_dquote; goto quoted; case '`': - func |= str_xquote; + func |= str_xquote; goto quoted; + case '/': + func |= str_regexp; quoted: newtok(); tokadd(func); @@ -6543,7 +6550,7 @@ parser_heredoc_identifier(struct parser_params *parser) lex_lastline); /* nd_orig */ nd_set_line(lex_strterm, ruby_sourceline); ripper_flush(parser); - return term == '`' ? tXSTRING_BEG : tSTRING_BEG; + return term == '`' ? tXSTRING_BEG : term == '/' ? tREGEXP_BEG : tSTRING_BEG; } static void @@ -6873,7 +6880,11 @@ parser_here_document(struct parser_params *parser, NODE *here) yylval.val, str); #endif heredoc_restore(lex_strterm); - lex_strterm = NEW_STRTERM(-1, 0, 0); + if (func & STR_FUNC_REGEXP) { + lex_strterm = NEW_STRTERM(-2, 0, 0); + } else { + lex_strterm = NEW_STRTERM(-1, 0, 0); + } set_yylval_str(str); return tSTRING_CONTENT; } diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index c135cec..15b03ff 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -528,7 +528,7 @@ def test_lineno_command_call_quote def assert_dedented_heredoc(expect, result, mesg = "") all_assertions(mesg) do |a| - %w[eos "eos" 'eos' `eos`].each do |eos| + %w[eos "eos" 'eos' `eos`, /eos/].each do |eos| a.for(eos) do assert_equal(eval("<<-#{eos}\n#{expect}eos\n"), eval("<<~#{eos}\n#{result}eos\n"))