Bug #18038
closedInvalid interpolation in heredocs
Description
Given code as followed:
var = 1
v1 = <<~CMD
something
#{"/#{var}"}
CMD
v2 = <<~CMD
something
#{other = "/#{var}"}
CMD
v3 = <<~CMD
something
#{("/#{var}")}
CMD
p v1
p v2
p v3
p v1 == v2
p v2 == v3
result of running this:
"something\n/\n"
"something\n/1\n"
"something\n/\n"
false
false
I would expect all heredocs to return the same value for all the cases. It seems the other
variable assignment should be irrelevant but only with it the value "1" is present.
Updated by maciej.mensfeld (Maciej Mensfeld) over 3 years ago
- Description updated (diff)
Updated by xtkoba (Tee KOBAYASHI) over 3 years ago
It seems that heredoc_dedent
in parse.y
interacts badly with some sort of interpolation optimizations.
A patch is shown below to disable such optimizations.
--- a/parse.y
+++ b/parse.y
@@ -10184,7 +10184,9 @@ new_evstr(struct parser_params *p, NODE
switch (nd_type(node)) {
case NODE_STR:
nd_set_type(node, NODE_DSTR);
- case NODE_DSTR: case NODE_EVSTR:
+ case NODE_DSTR:
+ break;
+ case NODE_EVSTR:
return node;
}
}
Updated by eileencodes (Eileen Uchitelle) over 3 years ago
I opened a PR here: https://github.com/ruby/ruby/pull/4664
I also confirmed that this is broken in the same way in Ruby 2.5, 2.6, and 2.7
Updated by eileencodes (Eileen Uchitelle) over 3 years ago
- Status changed from Open to Closed
Applied in changeset git|b940a453572b5c3ed5c0951647929e14f5843a7d.
Fix interpolated heredoc
This fixes https://bugs.ruby-lang.org/issues/18038. The provided
reproduction showed that this happens in heredocs with double
interpolation. In this case DSTR
was getting returned but needs to be
convered to a EVSTR
which is what is returned by the function. There
may be an additional bug here that we weren't able to produce. It seems
odd that STR
returns DSTR
while everything else should return
EVSTR
since the function is new_evstr
.
[Bug #18038][ruby-core:104597]
Co-authored-by: Aaron Patterson tenderlove@ruby-lang.org