-1

I'm trying to enumerate an array inside a string, and have the values of the array interpolate inside of string.

Example:

todos = ["sleep", "eat", "powernap"]

"Today I have todo: \n" +
'#{todos.each do |todo| }'
"\t #{todo}" +
'#{end}'

OUTPUT:

"Today I have todo: \n\tsleep\neat\npowernap"
Mitch Kroska
  • 325
  • 4
  • 15

2 Answers2

3

You're expecting #{...} to work like ERB's <%...%> or even PHP's <?php but that's not the case. The string interpolation must contain a complete, syntactically valid Ruby expression, and that bit of code is incomplete.

You can rework that to be a singular expression:

"Today I have todo: #{todos.join("\t "}"

Or you can do your iteration manually, though this is often sub-optimal in terms of performance:

todos.each_with_object("Today I have todo:") do |todo, buffer|
  buffer << "\t " << todo
end

As you can see the first version is significantly more concise.

Ruby's string interpolation options are unusually flexible, but they do require the code to be self-contained.

tadman
  • 208,517
  • 23
  • 234
  • 262
0

I assume you want this:

Today I have todo:
        sleep
        eat
        powernap

To do this you can use a map to wrap each element in a tab and newline, then join to turn the strings in the Array into a single string.

todos.map {|todo| "\t#{todo}\n"}.join("")

That will put a newline and tab around each element, and then concatenate each element together. Note that it's using the concatenation by using #{} to embed a variable in the string. It also could have been "\t" + todo + "\n", that is exactly the same.

The result is:

"\tsleep\n\teat\n\tpowernap\n"

Then you can concatenate that with the string, nothing special is needed.

puts "Today I have todo:\n" +
     todos.map {|todo| "\t#{todo}\n"}.join("") +
     "I hope I get them done!\n"

There's lots of ways to do it, but the important thing is it has to produce a String. each won't work because it will produce an Array and you'll get something like this:

Today I have todo:
    ["sleep", "eat", "powernap"]
I hope I get them done!

If you want to, you could do this as string interpolation by putting the whole expression into a #{} inside the string. Here's a simpler example that turns the list into a comma-separated string.

puts "Today I have todo: #{todos.join(", ")}\n"

Any expression can go into #{}, but #{} must contain a complete expression! Each #{} will be run on its own and each result will be concatenated into the string.

Schwern
  • 153,029
  • 25
  • 195
  • 336