tags:

views:

384

answers:

5

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
+3  A: 

Use <<- operator:

code = <<-CODE
var1 = "foo"
var2 = "bar"
CODE
Eimantas
This looks pretty good (I guess it's a HERE document), but it preserves white space at the beginning of the lines. any way to get rid of that?
Peter
`code = <<-CODE.gsub(/^\s+/,'')` followed by the heredoc as usual.
glenn jackman
close, but I want it to preserve indentation, too... it's just the *extra* whitespace that should be gone. yep, I know a workaround, but it's ugly.
Peter
Why would you want to preserve indentation in HEREdoc? o0
Eimantas
+4  A: 

This would be one way:

code = []
code << "next line of code #{something}"
code << "another line #{some_included_expression}"
code.join("\n")
Jim
+1  A: 

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.

Peter
Instead of having to put a " |" prefix for each line AND also changing the String class, why not just use "code << " as in my answer. You can shorten the 'code' variable name to be 'd'. It's easy to understand and any Ruby programmer should be able to figure it out.
Jim
+1  A: 

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"
DigitalRoss
+2  A: 

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"
Harpastum