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 `’
(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 ?

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 Bug #5156: Problem with creating a SHA2 digest hash when string has character sequence "#$" - Ruby 1.8 - Ruby Issue Tracking System , reporting this issue,
closed as “Rejected”.

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.

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

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 Tue, May 28, 2013 at 4:31 PM, Tadeusz B.
[email protected]wrote:

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.

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 ?

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

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

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 ?

On 2013-05-29, at 6:29 AM, Tadeusz B. [email protected] wrote:

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

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


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

Mike ᒩ Stok [email protected]
http://www.stok.ca/~mike/

The “`Stok’ disclaimers” apply.

On 2013-05-29, at 8:57 AM, Tadeusz B. [email protected] 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/.

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

Mike S. [email protected]
http://www.stok.ca/~mike/

The “`Stok’ disclaimers” apply.

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

On Tue, May 28, 2013 at 5:31 PM, Tadeusz B.
[email protected]wrote:

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 Wed, May 29, 2013 at 4:52 AM, Tadeusz B. [email protected]
wrote:

 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#$