AAARRRRGH! s="#$" => SyntaxError: compile error

Hi.
I get the following error from the following statement :
s="#$"

irb(main):001:0> s="#$"
SyntaxError: (irb):1: unterminated string meets end of file
        from C:/Ruby200/bin/irb:12:in `<main>'
(A similar response from 1.8.6 on HPUX.)

Also,

irb(main):011:0> s="#$!"
=> ""

Something is broken. Does anyone know whats going on with this ?

s="#"+"$" and s="#\$" work ok, but that does not help when the
string occurs in data which goes into eval.

Also, this is not good
irb(main):008:0> s=("xxxxxx.....#$yyyyyyyyy")
=> "xxxxxx....."

Is there a fundamental problem with the Ruby parser ?
or is this just an isolated glitch ?

···

--
Posted via http://www.ruby-forum.com/.

Ah, I've found it now: the hash is treated as beginning string interpolation, the $ as the beginning of a global variable name, the quote as the rest of variable name, and then you have no closing quote.

Compare this with:

irb(main):001:0> $a = 5
=> 5
irb(main):003:0> "#{$a}"
=> "5"
irb(main):002:0> "#$a"
=> "5"
irb(main):004:0> "#{$"}"
=> (lots of stuff)

("#$"" is valid, too, but doesn't work in IRB.)

Also see http://bugs.ruby-lang.org/issues/5156 , reporting this issue, closed as "Rejected".

···

--
Matma Rex

I can reproduce the issue. Weird.

Although, when you construct the string somehow (such as using '#'+'$', as you mentioned), then inspect it, it shows as "\#$", leading me to believe that this bizarre behavior is, in fact, some sort of a feature, if #inspect knows about this and produces a string that parses.

···

--
Matma Rex

Hi.
I get the following error from the following statement :
s="#$"

irb(main):001:0> s="#$"
SyntaxError: (irb):1: unterminated string meets end of file
        from C:/Ruby200/bin/irb:12:in `<main>'
(A similar response from 1.8.6 on HPUX.)

Also,

irb(main):011:0> s="#$!"
=> ""

Something is broken. Does anyone know whats going on with this ?

This is because when interpolating global variables in a string, you're
allowed to omit the curly braces.

The following are equivalent:

$ irb

$greeting = "Hello"
puts "#$greeting world."

Hello world

puts "#{$greeting} world."

Hello world

So, you're string "#$" makes ruby think you're about to interpolate a
global variable. However, you then fail to provide the name of a global.

···

On Tue, May 28, 2013 at 4:31 PM, Tadeusz Bochan <lists@ruby-forum.com>wrote:

s="#"+"$" and s="#\$" work ok, but that does not help when the
string occurs in data which goes into eval.

Also, this is not good
irb(main):008:0> s=("xxxxxx.....#$yyyyyyyyy")
=> "xxxxxx....."

Is there a fundamental problem with the Ruby parser ?
or is this just an isolated glitch ?

--
Posted via http://www.ruby-forum.com/\.

--
Kendall Gifford
zettabyte@gmail.com

Hi.
I get the following error from the following statement :
s="#$"

This is global var interpolation, more or less the same as:

s="#{$"}

And so you can see why the parser is expecting a terminal double quote.

For example:

>> Process.pid
=> 4574
>> $$
=> 4574
>> "#$$"
=> "4574"
>> "#{$$}"
=> "4574"

···

On 05/28/2013 03:31 PM, Tadeusz Bochan wrote:

Thank you for all the replies.

I didn't know about the interpolation without {}.

The way I first saw the problem was :
I have a program (non-ruby) which dumps items out of a database in a
format which is compatible with "inspect".

So, to read this, I was using "eval".
eg., text='"ABC\267#$"'
     data=eval(text)

It just so happened that one of the data items contained "#$".

My workaround for the moment is : data=eval(text.gsub("#",'\\043'))
Any better suggestions ?

···

--
Posted via http://www.ruby-forum.com/.

Ooops. Spoke too soon. The workaround doesn't.

"xyz#abc".gsub("#","\\043") => "xyz#43abc"

···

--
Posted via http://www.ruby-forum.com/.

This workaround (avoiding eval) works, but is ever so slow !!

# convert all \nnn to corresponding character
data=text.gsub(/\\[0-7]{3,4}/) {|r| r.scanf("%c%o").last.chr}

Can any one suggest something better please ?

···

--
Posted via http://www.ruby-forum.com/.

Hi Mike,
Your suggestions worked fine, but eval has sprung another leak on me,
and I haven't worked out quite what it is yet.
Using eval on this problem was not such a good idea after all ;-[[
[1] pry(main)> puts "xyz#abc".gsub("#","\\\\043");
xyz\043abc
[2] pry(main)> puts "xyz#abc".gsub("#") { '\\043' };
xyz\043abc

···

--
Posted via http://www.ruby-forum.com/.

Hi.
I get the following error from the following statement :
s="#$"

irb(main):001:0> s="#$"
SyntaxError: (irb):1: unterminated string meets end of file
        from C:/Ruby200/bin/irb:12:in `<main>'
(A similar response from 1.8.6 on HPUX.)

Also,

irb(main):011:0> s="#$!"
=> ""

Something is broken. Does anyone know whats going on with this ?

As stated, #$... in a String will interpolate the $... In your case, there
is a global variable `$"` which it is trying to interpolate, so you think
you're ending the string, but really, that second quotation is part of the
variable name (I assume this was all inherited from Perl). You would need
to do "#$"" For whatever reason, this doesn't work in irb, but it does work
in a Ruby program: ruby -e 'p "#$""'

Anyway, to get around this, escape the hash so that it isn't looked at as
interpolating: ruby -e 'p "\#$"'

Also, this is not good
irb(main):008:0> s=("xxxxxx.....#$yyyyyyyyy")
=> "xxxxxx....."

Again, just escape the hash
s= "xxxxxx.....\#$yyyyyyyyy"

Is there a fundamental problem with the Ruby parser ?
or is this just an isolated glitch ?

No, it's just unintuitive.

···

On Tue, May 28, 2013 at 5:31 PM, Tadeusz Bochan <lists@ruby-forum.com>wrote:

On Wed, May 29, 2013 at 4:52 AM, Tadeusz Bochan <lists@ruby-forum.com> wrote:

Thank you for all the replies.

I didn't know about the interpolation without {}.

The way I first saw the problem was :
I have a program (non-ruby) which dumps items out of a database in a
format which is compatible with "inspect".

So, to read this, I was using "eval".
eg., text='"ABC\267#$"'
     data=eval(text)

It just so happened that one of the data items contained "#$".

My workaround for the moment is : data=eval(text.gsub("#",'\\043'))
Any better suggestions ?

I don't understand this, why do you want to eval "ABC\267\#$"? It is not
valid Ruby (ignoring the nonsenical characters, it would mean 'look up the
constant ABC', which is presumably not what you're intending). Can you give
examples of inputs and outputs?

josh-cheek wrote : why do you want to eval "ABC\267\#$"? It is not valid
Ruby
Hi Josh,
Basicaly, I need an un-inspect method.
ie., data == data.inspect.uninspect

This snippet may help clarify :

line=DATA.read
p eval '"'+line+'"'
__END__
abc#\101xyz#$

this fails - the expected output would be abc#Axyz#$

···

--
Posted via http://www.ruby-forum.com/.

There are a couple of ways to do that:

[1] pry(main)> puts "xyz#abc".gsub("#","\\\\043");
xyz\043abc
[2] pry(main)> puts "xyz#abc".gsub("#") { '\\043' };
xyz\043abc

There's an explanation of how the replacement string is double interpolated at Gsub("\\", "\\\\") seems unintuitive - Ruby - Ruby-Forum

Hope this helps,

Mike

···

On 2013-05-29, at 6:29 AM, Tadeusz Bochan <lists@ruby-forum.com> wrote:

Ooops. Spoke too soon. The workaround doesn't.

"xyz#abc".gsub("#","\\043") => "xyz#43abc"

--
Posted via http://www.ruby-forum.com/\.

--

Mike ᒩ Stok <mike@stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.

Watch out for the 3 or 4 digit thing there, how can you tell the difference between a value encoded as 3 digits which happens to be followed by a "real" octal digit from the un-encoded data? you either need an explicit terminator e.g. \0123; or \012; or to guarantee the length of the encoded representation. Additionally you need to make sure any literal \ in the input are encoded too so you don't accidentally un-encode sequences which were in your original data.

text.gsub(/\\([0-7]{3})/) { $1.to_i(8).chr }

might be faster.

Hope this helps,

Mike

···

On 2013-05-29, at 8:57 AM, Tadeusz Bochan <lists@ruby-forum.com> wrote:

This workaround (avoiding eval) works, but is ever so slow !!

# convert all \nnn to corresponding character
data=text.gsub(/\\[0-7]{3,4}/) {|r| r.scanf("%c%o").last.chr}

Can any one suggest something better please ?

--
Posted via http://www.ruby-forum.com/\.

--

Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.