Project

General

Profile

Bug #14584

Squigly heredoc with interpolation that has a string literal withe spaces gets incorrect value

Added by asterite (Ary Borenszweig) almost 2 years ago. Updated over 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin17]
[ruby-core:85983]

Description

Given this program:

text1 = <<~FOO
  one#{"   two   "}
  FOO

text2 = <<~FOO
one#{"   two   "}
FOO

p text1
p text2

The output is:

"one two   \n"
"one   two   \n"

The two should be equal.

I think the problem happens because squigly heredoc will remove the first two spaces from each line in the heredoc, but it seems to also be removing it from literals inside interpolation inside a heredoc.


Related issues

Related to Ruby master - Bug #11989: Dedenting interpolating heredoc can interpret escapes incorrectlyClosedActions

Associated revisions

Revision f2b094a5
Added by nobu (Nobuyoshi Nakada) almost 2 years ago

parse.y: fix interpolated string literal dedent

  • parse.y (heredoc_dedent): fix interpolated string literal dedent,
    remove indentations from only nodes with the newline flag.
    [ruby-core:85983] [Bug #14584]

  • parse.y (here_document): set the newline flag on literal string
    nodes starting at the beginning of line.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62724 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 62724
Added by nobu (Nobuyoshi Nakada) almost 2 years ago

parse.y: fix interpolated string literal dedent

  • parse.y (heredoc_dedent): fix interpolated string literal dedent,
    remove indentations from only nodes with the newline flag.
    [ruby-core:85983] [Bug #14584]

  • parse.y (here_document): set the newline flag on literal string
    nodes starting at the beginning of line.

Revision 62724
Added by nobu (Nobuyoshi Nakada) almost 2 years ago

parse.y: fix interpolated string literal dedent

  • parse.y (heredoc_dedent): fix interpolated string literal dedent,
    remove indentations from only nodes with the newline flag.
    [ruby-core:85983] [Bug #14584]

  • parse.y (here_document): set the newline flag on literal string
    nodes starting at the beginning of line.

Revision 2bedc514
Added by naruse (Yui NARUSE) over 1 year ago

merge revision(s) 62723,62724: [Backport #14584]

    parse.y: reduce duplicate code

    parse.y: fix interpolated string literal dedent

    * parse.y (heredoc_dedent): fix interpolated string literal dedent,
      remove indentations from only nodes with the newline flag.
      [ruby-core:85983] [Bug #14584]

    * parse.y (here_document): set the newline flag on literal string
      nodes starting at the beginning of line.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@62909 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 62909
Added by naruse (Yui NARUSE) over 1 year ago

merge revision(s) 62723,62724: [Backport #14584]

    parse.y: reduce duplicate code

    parse.y: fix interpolated string literal dedent

    * parse.y (heredoc_dedent): fix interpolated string literal dedent,
      remove indentations from only nodes with the newline flag.
      [ruby-core:85983] [Bug #14584]

    * parse.y (here_document): set the newline flag on literal string
      nodes starting at the beginning of line.

History

Updated by sikachu (Prem Sichanugrist) almost 2 years ago

👍 I can confirm this bug exists in 2.5.0p0.

Also, it seems like the number of spaces it's removing is based on the gutter size as well (which is expected?)

# two spaces gutter, four leading spaces in literal
<<~FOO
  two#{"    four    "}
FOO
#=> "two  four    \n"

# two spaces gutter, five leading spaces in literal
<<~FOO
  two#{"     five     "}
FOO
#=> "two   five     \n"

# three spaces gutter, five leading spaces in literal
<<~FOO
   three#{"     five     "}
FOO
#=> "three  five     \n"

I don't have enough Ruby lexer knowledge to fix this, so I hope someone will be able to spare their time taking care of this 🙇‍♂️

Updated by asterite (Ary Borenszweig) almost 2 years ago

Interestingly enough, it doesn't happen when you have:

text1 = <<~FOO
  one#{"   two   " * 1}
  FOO

So it seems Ruby does this only when the interpolation has a string literal, presumably to optimize that out and embed it into the resulting heredoc string.

#3

Updated by nobu (Nobuyoshi Nakada) almost 2 years ago

  • Related to Bug #11989: Dedenting interpolating heredoc can interpret escapes incorrectly added
#4

Updated by nobu (Nobuyoshi Nakada) almost 2 years ago

  • Backport changed from 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN to 2.3: REQUIRED, 2.4: REQUIRED, 2.5: REQUIRED
  • Description updated (diff)
#5

Updated by nobu (Nobuyoshi Nakada) almost 2 years ago

  • Status changed from Open to Closed

Applied in changeset trunk|r62724.


parse.y: fix interpolated string literal dedent

  • parse.y (heredoc_dedent): fix interpolated string literal dedent,
    remove indentations from only nodes with the newline flag.
    [ruby-core:85983] [Bug #14584]

  • parse.y (here_document): set the newline flag on literal string
    nodes starting at the beginning of line.

Updated by naruse (Yui NARUSE) over 1 year ago

  • Backport changed from 2.3: REQUIRED, 2.4: REQUIRED, 2.5: REQUIRED to 2.3: REQUIRED, 2.4: REQUIRED, 2.5: DONE

ruby_2_5 r62909 merged revision(s) 62723,62724.

Also available in: Atom PDF