I think I'm really trying to do some strange things with string
interpolation and I'm not sure if what I want to do is completly
possible...
Anyway, in case you missed the other thread about the Ruby Templating
System, this is related to that. It basically allows you to embed Ruby
code into a text file - the text file is read into a string and and
eval'ed to create the output string. Works great if all the code between
the '#{' and '}' is on one line, but doesn't work so well if it isn't -
that's the problem I'm trying to fix right now.
Let's say I have the following code:
i=5
s = "x"
newline = "\n"
str = 'start:\n#{string = ""; \
i.times { |j| \
string << "line:#{j.to_s+newline}"\
}; string} end:'
puts str.inspect
#output=> "start:\\n #{string = \"\"; i.times {
|j|
string << \"line:#{j.to_s+newline}\" }; string} end:"
puts eval str.inspect
#output=>start:\n line:0
line:1
line:2
line:3
line:4
end:
Problem 1: The only way I can seem to get a newline is to actually define
'newline="\n"' before the string and use the 'newline' variable in the
string. Doing str.inspect escapes the '\n' of the original string
resulting in '\\n'.
Problem 2: Ruby code in '#{ }' spanning multiple lines. Let's say I put
the string above into a file called 'junk' (except that I get rid of the
'\''s at the end of the lines) and run the following:
#test2.rb
i=5
newline = "\n"
filestring = ""
File.foreach("junk") { |line|
filestring << line
}
puts filestring.inspect
puts eval filestring.inspect
The output from filestring.inspect is:
"start:\\n#{string = \"\"; \n i.times { |j| \n
string << \"line:#{j.to_s+newline}\"\n }; string} end:\n"
The output from eval'ing filestring.inspect is:
test2.rb:8: (eval):1: compile error in string expansion (SyntaxError)
(eval):1: parse error
string = ""; \n i.times { |j| \n string
<< "line:#{j.to_s+newline}"\n }; string
^
The error seems to be in an odd place in the string...
Now if I get rid of all newlines in the file 'junk' so that it looks like:
start:\n#{string = ""; i.times { |j| string << "line:#{j.to_s+newline}"
}; string} end:
....and then run: ruby test2.rb again:
The output from filestring.inspect is:
"start:\\n#{string = \"\"; i.times { |j| string << \"line:#{j.to_s+newline}\" }; string} end:\n"
The output from eval'ing filestring.inspect is:
start:\nline:0
line:1
line:2
line:3
line:4
end:
Which (except for the '\n') is what I want. The only difference was that
in the first case the contents of junk looked like:
start:\n#{string = "";
i.times { |j|
string << "line:#{j.to_s+newline}"
}; string} end:
I'm not sure why this is changing the outcome. I would think that the
parser, as called by eval, should be able to handle the newlines just as it
does in a regular ruby program. What am I missing?
Phil