From: ptkwt@...1.aracnet.com (Phil Tomson) Date: 2001-10-31T16:36:00+09:00 Subject: [ruby-talk:23918] question about string interpolation and '#{}' 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