Professional Web Applications Themes

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

From the Programming Ruby book: <quote> In addition, you can substitute the value of any Ruby expression into a string using the sequence #{ expr }. </quote> 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}></user>" This prints exactly what I want it to print, namely: <user name="peter" ></user> One would expect that substituting the RHS of the assignment to temp for ...

  1. #1

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

    From the Programming Ruby book:
    <quote>
    In addition, you can substitute the value of any Ruby expression
    into a string using the sequence #{ expr }.
    </quote>

    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}></user>"

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

    <user name="peter" ></user>

    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 + "\""}></user>"

    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
    </user> 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 Guest

  2. #2

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

    Peter wrote:
    >>From the Programming Ruby book:
    > <quote>
    > In addition, you can substitute the value of any Ruby expression
    > into a string using the sequence #{ expr }.
    > </quote>
    >
    > 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}\"></user>"

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

    Hal



    Hal Fulton Guest

  3. #3

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

    Peter wrote:
    >>From the Programming Ruby book:
    ><quote>
    > In addition, you can substitute the value of any Ruby expression
    > into a string using the sequence #{ expr }.
    ></quote>
    >
    >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}></user>"
    >
    >This prints exactly what I want it to print, namely:
    >
    > <user name="peter" ></user>
    >
    >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 + "\""}></user>"
    >
    >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
    ></user> 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 + '\"'}></user>"

    This works, don't know about why the other one doesn't though.....

    Michael



    Michael Garriss Guest

  4. #4

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

    > 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}\"></user>"
    >
    > 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


    Peter Guest

  5. #5

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


    On Tuesday, September 16, 2003, at 06:12 PM, Peter wrote:
    > From the Programming Ruby book:
    > <quote>
    > In addition, you can substitute the value of any Ruby expression
    > into a string using the sequence #{ expr }.
    > </quote>
    >
    > [snip]
    > name = "peter"
    > temp = "name=\"" + name + "\""
    > print "<user #{temp}></user>"
    > [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]
    As you may have already discovered, the following gives the expected
    results:

    print "<user #{"name=" + name + ""}></user>"

    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


    Mark Wilson Guest

  6. #6

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

    Peter wrote:
    >>FWIW, this avoids it:
    >>
    >> name = "peter"
    >> print "<user name=\"#{name}\"></user>"
    >>
    >>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


    Hal Fulton Guest

  7. #7

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

    > As you may have already discovered, the following gives the expected
    > results:
    >
    > print "<user #{"name=" + name + ""}></user>"
    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


    Peter Guest

  8. #8

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


    Previously, I wrote:
    > [snip]
    > As you may have already discovered, the following gives the expected
    > results:
    >
    > print "<user #{"name=" + name + ""}></user>"
    >
    Upon further reflection, this does what you want:

    print "<user #{'name="' + name + '"'}></user>"
    > [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


    Mark Wilson Guest

  9. #9

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

    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


    Hal Fulton Guest

  10. #10

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

    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.
    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
    --
    [email]timbates.id.au[/email]

    Tim Bates Guest

  11. #11

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


    On Tuesday, September 16, 2003, at 07:04 PM, Peter wrote:
    > [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


    Mark Wilson Guest

  12. #12

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

    > is a lot for the interpreter to handle if one also wants to preserve a
    > semlance of readability.
    Readability is subjective. Besides, good syntax highlighting can really
    help in this case ;-) And also, interpreters (and the prs they use for
    reading my ruby jumble) don't really have a problem with readability. We
    humans are much more demanding.

    Peter


    Peter Guest

  13. #13

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

    P> print "<user #{"name=\"" + name + "\""}></user>"
    ...
    P> AFAICS, it is grammatically perfectly sound.
    ...
    H> I agree, it seems like a reasonable construction.

    I investigated this a little bit. The relevant code starts at line 4079
    in p.y. I am not familiar enough with the inner workings of p.y to
    see offhand what this code is trying to do, but it was obviously inserted to
    specifically catch this situation. This may simply be a limitation in the
    way quoting is implemented.

    P> Maybe we should ask Matz...
    H> I think we should. Or we just did.

    I third the motion!

    - Warren Brown


    Warren Brown Guest

  14. #14

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

    > I wonder if it's one of those things that is made difficult
    > by the use of yacc?
    AFAIK, it is not. It's not really the usual construction in a language
    since it requires the lexer to have some kind of state to have it
    differentiate between a simple '}' and one that resumes a string as in my
    example above. flex, which is used in combination with yacc, allows for
    start conditions, and that is just what is needed. I'd say it increases
    code size, not complexity.

    Peter


    Peter Guest

  15. #15

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

    To combine two of my e-mails into one:

    1. double-quote as beginning of string literal,
    2. string interpolation open,
    3. double-quote as beginning of string literal,
    4. double-quote as character,

    Trying to do 4. by escaping the double-quote renders the double quote
    an end of string literal marker.

    The following does not work as intended (the expression is evaluated
    differently than it would be in a variable assignment):

    print "<user #{"name=\"" + name + \""}></user>"

    The effect in 4. can be done by enclosing the string literal inside the
    string interpolation in single-quotes.

    alternate 3. single-quote as beginning of string literal,
    alternate 4. double-quote as character

    The following does work as intended:

    print "<user #{'name="' + name + '"'}></user>"

    5. double-quote as end of string literal,
    alternate 5. single-quote as end of string literal,
    6. string interpolation close, and
    7. double-quote as end of string literal

    As to why, I don't know. As to whether it is necessary that it be this
    way, I don't know.

    Regards,

    Mark



    Mark Wilson Guest

  16. #16

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

    > As to why, I don't know. As to whether it is necessary that it be this
    > way, I don't know.
    I don't know either. What I do know is that the expression I wrote down
    made sense to me, and that the Principle of Least Surprise says that it
    then also should to the ruby interpreter, but it did not (forgive me the
    blasphemy). I'm curious as to what the problem is rather than interested
    in knowing all possible work-arounds. The latter was never the intention
    of my initial e-mail (but thanks anyway for the many replies, I can see
    now why people exclaim that they love the ruby community :-) I'll wait for
    Matz to show up.

    Regards,
    Peter


    Peter Guest

  17. #17

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

    Hi,

    At Wed, 17 Sep 2003 08:04:18 +0900,
    Peter wrote:
    > > As you may have already discovered, the following gives the expected
    > > results:
    > >
    > > print "<user #{"name=" + name + ""}></user>"
    >
    > It does not since I want quotes around the name...
    These work as expected, and are faster.

    print "<user name=\"#{name}\"}></user>"
    print %{<user name="#{name}"}></user>}
    > 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.

    --
    Nobu Nakada

    nobu.nokada@softhome.net Guest

  18. #18

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

    On Wednesday, 17 September 2003 at 7:12:16 +0900, Peter wrote:
    > name = "peter"
    > print "<user #{"name=\"" + name + "\""}></user>"
    >
    When I see a line like this, my first question is why not
    write it like:

    print "<user name=\"#{name}\"></user>"

    It looks cleaner and avoids all the hassle and confusion.

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

    Jim Freeze Guest

  19. #19

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

    Hi,

    In message "#{} and \" don't like each other"
    on 03/09/17, Peter <Peter.Vanbroekhovencs.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 + "\""}></user>"

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

    print "<user #{'name="' + name + '"'}></user>\n"

    Only Nobu knows this part of the pr.

    matz.

    Yukihiro Matsumoto Guest

  20. #20

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

    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 + '"'}></user>\n"
    >
    > Only Nobu knows this part of the pr.
    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


    Ben Giddings Guest

Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 1
    Last Post: April 24th, 01:27 PM
  2. CFINPUT type="radio" w/ "value" requires "label"
    By Iceborer in forum Macromedia ColdFusion
    Replies: 2
    Last Post: February 21st, 06:16 PM
  3. #26162 [NEW]: $a="0abcdefg";if ($a==0) echo "OK"; result is "OK" ?!
    By zhuminglun at yahoo dot com dot cn in forum PHP Development
    Replies: 0
    Last Post: November 7th, 12:04 PM
  4. Replies: 0
    Last Post: November 7th, 11:45 AM
  5. "Start" "Program" "Menu" list is empty
    By Pete in forum Windows XP/2000/ME
    Replies: 2
    Last Post: July 10th, 10:42 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139