#{} and \" don't like each other

From the Programming Ruby book:

In addition, you can substitute the value of any Ruby expression
into a string using the sequence #{ expr }.

Up to about an hour ago, I never doubted this statement. I’ve stumbled
upon the following example which is not accepted by ruby. The following
piece of code works perfectly, as to be expected:

name = “peter"
temp = “name=”” + name + “”"
print “<user #{temp}>”

This prints exactly what I want it to print, namely:

One would expect that substituting the RHS of the assignment to temp for
temp in the third statement, would work as well:

name = “peter"
print “<user #{“name=”” + name + “””}>"

Type this in at the ruby prompt and you’ll soon notice that it gives you
the following prompt and not the expected output as above:

irb(main):003:-1/

Note the -1 in the prompt, meaning ruby managed to get above the toplevel.

Ruby just keeps waiting for input, and I can type anything but ruby will
stay in this state until I type a / and then unhappily states this:

(irb):2: warning: escaped terminator ‘"’ inside string interpolation
SyntaxError: compile error
(irb):3: unterminated string meets end of file
(irb):3: syntax error
from (irb):3

Anyway, what happens is that the escaped quotes are misinterpreted since
the problem is gone when I leave them out. The effect is that the slash in
is interpreted as the start of a regular expression. This can only
be if ruby thinks it’s not part of a string string, which was clearly not
my intention.

Can someone please tell me whether this is a bug, or otherwise why I
shouldn’t have done the above.

Note: I’m using version 1.8.0 of ruby, don’t know if the trueness of the
above statement from Programming Ruby changed as the ruby version changed.

Thanks,
Peter

Peter wrote:

From the Programming Ruby book:

In addition, you can substitute the value of any Ruby expression
into a string using the sequence #{ expr }.

Up to about an hour ago, I never doubted this statement. I’ve stumbled
upon the following example which is not accepted by ruby.

Fulton’s Third Law says that there is an exception to every rule,
except Fulton’s Third Law.

Can someone please tell me whether this is a bug, or otherwise why I
shouldn’t have done the above.

Truthfully, I’m not sure why this happens. But since the
warning is accurate and explicit, I don’t think it’s a bug,
but perhaps one of those features that’s it’s not immediately
obvious we need.

FWIW, this avoids it:

name = “peter”
print “<user name="#{name}">”

So it evidently has to do specifically with the escaped terminator
inside the interpolated part.

Hal

Peter wrote:

From the Programming Ruby book:

In addition, you can substitute the value of any Ruby expression
into a string using the sequence #{ expr }.

Up to about an hour ago, I never doubted this statement. I’ve stumbled
upon the following example which is not accepted by ruby. The following
piece of code works perfectly, as to be expected:

name = “peter”
temp = “name="” + name + “"”
print “<user #{temp}>”

This prints exactly what I want it to print, namely:

One would expect that substituting the RHS of the assignment to temp for
temp in the third statement, would work as well:

name = “peter”
print “<user #{“name="” + name + “"”}>”

Type this in at the ruby prompt and you’ll soon notice that it gives you
the following prompt and not the expected output as above:

irb(main):003:-1/

Note the -1 in the prompt, meaning ruby managed to get above the toplevel.

Ruby just keeps waiting for input, and I can type anything but ruby will
stay in this state until I type a / and then unhappily states this:

(irb):2: warning: escaped terminator ‘"’ inside string interpolation
SyntaxError: compile error
(irb):3: unterminated string meets end of file
(irb):3: syntax error
from (irb):3

Anyway, what happens is that the escaped quotes are misinterpreted since
the problem is gone when I leave them out. The effect is that the slash in
is interpreted as the start of a regular expression. This can only
be if ruby thinks it’s not part of a string string, which was clearly not
my intention.

Can someone please tell me whether this is a bug, or otherwise why I
shouldn’t have done the above.

Note: I’m using version 1.8.0 of ruby, don’t know if the trueness of the
above statement from Programming Ruby changed as the ruby version changed.

print “<user #{‘name="’ + name + ‘"’}>”

This works, don’t know about why the other one doesn’t though…

Michael

As you may have already discovered, the following gives the expected
results:

print “<user #{“name=” + name + “”}>”

In the variable assignment, you need to escape the quotes because
otherwise the literal string you are creating would be considered
terminated. Inside a literal string, inside #{}, it’s not necessary,
because we indicate the end of the expression to be interpolated with
an unescaped ‘}’. In addition, if we interpreted ‘"’ inside #{}, we
would not be able to terminate the parent string literal after the
appearance of ‘#{’, which would be bad (because there is a sequence of
characters we can’t put in a string literal, ever).

Regards,

Mark

···

On Tuesday, September 16, 2003, at 06:12 PM, Peter wrote:

From the Programming Ruby book:

In addition, you can substitute the value of any Ruby expression
into a string using the sequence #{ expr }.

[snip]

name = “peter”
temp = “name="” + name + “"”
print “<user #{temp}>”

[snip]

One would expect that substituting the RHS of the assignment to temp
for
temp in the third statement, would work as well:

[snip]

(irb):2: warning: escaped terminator ‘"’ inside string interpolation
SyntaxError: compile error
(irb):3: unterminated string meets end of file
(irb):3: syntax error
from (irb):3

Anyway, what happens is that the escaped quotes are misinterpreted
since
the problem is gone when I leave them out.

[snip]

When I see a line like this, my first question is why not
write it like:

print “<user name="#{name}">”

It looks cleaner and avoids all the hassle and confusion.

···

On Wednesday, 17 September 2003 at 7:12:16 +0900, Peter wrote:

name = “peter”
print “<user #{“name="” + name + “"”}>”


Jim Freeze

Enzymes are things invented by biologists that explain things which
otherwise require harder thinking.
– Jerome Lettvin

Hi,

···

In message “#{} and " don’t like each other” on 03/09/17, Peter Peter.Vanbroekhoven@cs.kuleuven.ac.be writes:

One would expect that substituting the RHS of the assignment to temp for
temp in the third statement, would work as well:

name = “peter”
print “<user #{“name="” + name + “"”}>”

I consider it as a bug. Avoid escaped double quotes in the string
interpolation until it’s fixed, e.g.

print “<user #{'name=”’ + name + ‘"’}>\n"

Only Nobu knows this part of the parser.

						matz.

Truthfully, I’m not sure why this happens. But since the
warning is accurate and explicit, I don’t think it’s a bug,
but perhaps one of those features that’s it’s not immediately
obvious we need.

The following simple expression gives exactly the same error message

“#{"}”

In this case I’d expect that error message…

FWIW, this avoids it:

name = “peter”
print “<user name="#{name}">”

So it evidently has to do specifically with the escaped terminator
inside the interpolated part.

I know this avoids it, but it was when the name="#{name}" needed to
become optional, I moved it all inside the #{} and used the ? : operator
to either generate the “name="” + name + “"” or else a simple “”.

Peter

As you may have already discovered, the following gives the expected
results:

print “<user #{“name=” + name + “”}>”

It does not since I want quotes around the name…

In the variable assignment, you need to escape the quotes because
otherwise the literal string you are creating would be considered
terminated. Inside a literal string, inside #{}, it’s not necessary,
because we indicate the end of the expression to be interpolated with
an unescaped ‘}’. In addition, if we interpreted ‘"’ inside #{}, we
would not be able to terminate the parent string literal after the
appearance of ‘#{’, which would be bad (because there is a sequence of
characters we can’t put in a string literal, ever).

I really don’t see the problem with interpreting what I wrote. On
encountering ‘#{’ in a string literal, anything up to the first unbalanced
‘}’ can be interpreted as any general ruby expression, including ‘"’ in
string literals within that expression, and after encountering the
unbalanced ‘}’ the reading of the original string is resumed until the
closing quote. AFAICS, it is grammatically perfectly sound.

Maybe we should ask Matz…

Peter

Previously, I wrote:

[snip]
As you may have already discovered, the following gives the expected
results:

print “<user #{“name=” + name + “”}>”

Upon further reflection, this does what you want:

print “<user #{'name=”’ + name + ‘"’}>"

[snip]

Inside a literal string, inside #{}, it’s not necessary, because we
indicate the end of the expression to be interpolated with an
unescaped ‘}’.

The above is wrong.

[snip]

Regards,

Mark

So what your saying is, Fulton’s Third Law has no exception? Does that
not make the Law its own exception? And if it has an exception, does
that not make the second clause paradoxical, or at least wrong?

Or was that the point?

Tim Bates

···

On Wed, Sep 17, 2003 at 07:29:04AM +0900, Hal Fulton wrote:

Fulton’s Third Law says that there is an exception to every rule,
except Fulton’s Third Law.


tim@bates.id.au

Yukihiro Matsumoto wrote:

I consider it as a bug. Avoid escaped double quotes in the string
interpolation until it’s fixed, e.g.

print “<user #{'name=”’ + name + ‘"’}>\n"

Only Nobu knows this part of the parser.

Heh – a polite way of saying it’s Nobu’s bug. grin

But seriously, it sure is refreshing to know that matz will see an issue
within a day at the most, and will immediately know and say whether or
not it truly is a bug. Thanks matz (and Nobu too).

Ben

Hi,

···

At Wed, 17 Sep 2003 13:33:12 +0900, Yukihiro Matsumoto wrote:

One would expect that substituting the RHS of the assignment to temp for
temp in the third statement, would work as well:

name = “peter”
print “<user #{“name="” + name + “"”}>”

I consider it as a bug. Avoid escaped double quotes in the string
interpolation until it’s fixed, e.g.

I’ve thought, according to the thread from [ruby-dev:17421],
and [ruby-dev:17549], it’s intentional (but transitional).
It’s not tough to change it, will we do it now?


Nobu Nakada

In article 20030916222932.A81108@freeze.org,

···

Jim Freeze jim@freeze.org wrote:

On Wednesday, 17 September 2003 at 7:12:16 +0900, Peter wrote:

name = “peter”
print “<user #{“name="” + name + “"”}>”

When I see a line like this, my first question is why not
write it like:

print “<user name="#{name}">”

It looks cleaner and avoids all the hassle and confusion.

What about using %Q to pick your own delimieters e.g.

print %Q{}

I try to avoid \ wherever possible.

Hope this helps,

Mike


mike@stok.co.uk | The “`Stok’ disclaimers” apply.
http://www.stok.co.uk/~mike/ | GPG PGP Key 1024D/059913DA
mike@exegenix.com | Fingerprint 0570 71CD 6790 7C28 3D60
http://www.exegenix.com/ | 75D2 9EC4 C1C0 0599 13DA

Peter wrote:

FWIW, this avoids it:

name = “peter”
print “<user name="#{name}">”

So it evidently has to do specifically with the escaped terminator
inside the interpolated part.

I know this avoids it, but it was when the name="#{name}" needed to
become optional, I moved it all inside the #{} and used the ? : operator
to either generate the “name="” + name + “"” or else a simple “”.

Oh, yes. Of course.

Well, all I can say now is that it only seems to complain when the
escaped terminator is the same terminator that would end the string
that surrounds the interpolated piece.

So if you mix quotes (as in Michael Garriss’s reply) you should be OK.

Hal

Peter wrote:

I really don’t see the problem with interpreting what I wrote. On
encountering ‘#{’ in a string literal, anything up to the first unbalanced
‘}’ can be interpreted as any general ruby expression, including ‘"’ in
string literals within that expression, and after encountering the
unbalanced ‘}’ the reading of the original string is resumed until the
closing quote. AFAICS, it is grammatically perfectly sound.

I agree, it seems like a reasonable construction.

Maybe we should ask Matz…

I think we should. Or we just did.

I wonder if it’s one of those things that is made difficult
by the use of yacc?

Hal

[snip]

I really don’t see the problem with interpreting what I wrote. On
encountering ‘#{’ in a string literal, anything up to the first
unbalanced
‘}’ can be interpreted as any general ruby expression, including ‘"’
in
string literals within that expression, and after encountering the
unbalanced ‘}’ the reading of the original string is resumed until the
closing quote.

IANAIE (I am not an interpreter expert), but I think

double-quote as beginning of string literal,
string interpolation open,
double-quote as beginning of string literal,
double-quote as character,
double-quote as character,
double-quote as end of string literal,
string interpolation close, and
end of string literal

is a lot for the interpreter to handle if one also wants to preserve a
semlance of readability.

AFAICS, it is grammatically perfectly sound.

I can’t tell one way or the other.

Regards,

Mark

···

On Tuesday, September 16, 2003, at 07:04 PM, Peter wrote:

Hi,

As you may have already discovered, the following gives the expected
results:

print “<user #{“name=” + name + “”}>”

It does not since I want quotes around the name…

These work as expected, and are faster.

print “<user name="#{name}"}>”
print %{<user name=“#{name}”}>}

I really don’t see the problem with interpreting what I wrote. On
encountering ‘#{’ in a string literal, anything up to the first unbalanced
‘}’ can be interpreted as any general ruby expression, including ‘"’ in
string literals within that expression, and after encountering the
unbalanced ‘}’ the reading of the original string is resumed until the
closing quote. AFAICS, it is grammatically perfectly sound.

Yes, it can be interpreted as you expected, and may be in
future version. But it was different till 1.6, so “escaped
terminator” is warned and interpreted as sole terminator, for
backward compatibility.

···

At Wed, 17 Sep 2003 08:04:18 +0900, Peter wrote:


Nobu Nakada

Thanks also to Peter for getting it started and for persisting in
asking questions.

Regards,

Mark

···

On Wednesday, September 17, 2003, at 01:24 AM, Ben Giddings wrote:

[snip]

But seriously, it sure is refreshing to know that matz will see an
issue within a day at the most, and will immediately know and say
whether or not it truly is a bug. Thanks matz (and Nobu too).

Heh – a polite way of saying it’s Nobu’s bug. grin

But seriously, it sure is refreshing to know that matz will see an issue
within a day at the most, and will immediately know and say whether or
not it truly is a bug. Thanks matz (and Nobu too).

I think he deserves a thanks from me too. Especially from me since I
started all this :slight_smile:

And just for the record, the piece of code I gave was stripped down to
highlight the problem, rather than to highlight the kind of code I would
write. In many mailinglists/newsgroups this is considered good practice,
but I can see it led to some confusion as to the point of my question. A
hooray for Matz for getting the point immediately :slight_smile:

So long,
Peter

Hi,

···

In message “Re: #{} and " don’t like each other” on 03/09/17, nobu.nokada@softhome.net nobu.nokada@softhome.net writes:

I’ve thought, according to the thread from [ruby-dev:17421],
and [ruby-dev:17549], it’s intentional (but transitional).
It’s not tough to change it, will we do it now?

Please. 1.8.1 should work as it is.

						matz.