Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building multi-line strings, programmatically, in Ruby

Tags:

ruby

Here's something I often do when programming:

code = ''
code << "next line of code #{something}" << "\n"
code << "another line #{some_included_expression}" << "\n"

Is there some better way than having << "\n" or + "\n" on every line? This seems quite inefficient.

I'm interested in Ruby solutions, in particular. I'm thinking something like

code = string.multiline do
  "next line of code #{something}"
  "another line #{some_included_expression}"
end
like image 233
Peter Avatar asked Oct 12 '09 03:10

Peter


People also ask

How do you create a multiline string in Ruby?

Multiline Syntax in Ruby You can use the the syntax `<<-TEXT` to start a multiline string in Ruby.

How can you create multi line strings?

There are three ways to create strings that span multiple lines: By using template literals. By using the + operator – the JavaScript concatenation operator. By using the \ operator – the JavaScript backslash operator and escape character.

Can a string have multiple lines?

Raw StringsThey can span multiple lines without concatenation and they don't use escaped sequences. You can use backslashes or double quotes directly.


6 Answers

If you're looking to build a block of text, the easy way to do it is to just use the % operator. For example:

code = %{First line
second line
Third line #{2 + 2}}

'code' will then be

"First line\n second line\n Third line 4"
like image 159
Harpastum Avatar answered Oct 16 '22 09:10

Harpastum


This would be one way:

code = []
code << "next line of code #{something}"
code << "another line #{some_included_expression}"
code.join("\n")
like image 42
Jim Avatar answered Oct 16 '22 09:10

Jim


Use <<- operator:

code = <<-CODE
var1 = "foo"
var2 = "bar"
CODE
like image 38
Eimantas Avatar answered Oct 16 '22 11:10

Eimantas


It would work for you to just embed ...\n" in your strings, I suppose. Here is a fun way to do it:

class String
  def / s
    self << s << "\n"
  end
end

then

f = ""           # => ""
f / 'line one'   # => "line one\n"
f / 'line two'   # => "line one\nline two\n"
f / 'line three' # => "line one\nline two\nline three\n"

This would enable something like:

"" / "line 1" / "line 2" / "line 3" # => "line 1\nline 2\nline 3\n"

Or even:

f/
"line one"/
"line two"/
"line three"     # => "line one\nline two\nline three\n"
like image 32
DigitalRoss Avatar answered Oct 16 '22 11:10

DigitalRoss


Here's a method presented here:

str = <<end.margin
  |This here-document has a "left margin"
  |at the vertical bar on each line.
  |
  |  We can do inset quotations,
  |  hanging indentions, and so on.
end

This is accomplished by using this:

class String
  def margin
    arr = self.split("\n")             # Split into lines
    arr.map! {|x| x.sub!(/\s*\|/,"")}  # Remove leading characters
    str = arr.join("\n")               # Rejoin into a single line
    self.replace(str)                  # Replace contents of string
  end
end

I guess the question with this is: does the lack of portability / presence of monkey patching make this solution bad.

like image 42
Peter Avatar answered Oct 16 '22 11:10

Peter


What's wrong with:

code = "next line of code #{something}\n"+
       "another line #{some_included_expression}"
like image 42
jjnevis Avatar answered Oct 16 '22 11:10

jjnevis