While writing a spec that uses different chunks of csv and txt data I was wondering about the best way to define multi-line strings in array constants.
Normally, I would use Heredoc to define a single multi-line string like this:
CSV_CHUNK = <<-CSV 10, "a", "b" 20, "c", "d" 30, "e", "e" CSV
Perfect. The unattractiveness starts when adding more chunk definitions. It usually ends up with having CSV_CHUNK_0, CSV_CHUNK_1, CSV_CHUNK_3 and so on in place. Thats a bit unfortunately. For example this hinders to use normal array iteration like each and friends.
So, my question was if there is a way to simply add chunk after chunk to an array. Sure its possible:
chunks = [] chunks <<<<-CSV 10, "a", "b" 20, "c", "d" 30, "e", "f" CSV chunks <<<<-CSV 40, "a", "b" 50, "c", "d" 60, "e", "f" CSV
This is valid Ruby syntax. Actually its just the << method of Array plus the Heredoc syntax. ( Yes, you can add a space inbetween :) )
But, since we are altering a variable we can't use a constant here. To use a constant, we have to do the Heredoc definition inline in the Array declaration:
CHUNKS = [ <<-CSV , 10, "a", "b" 20, "c", "d" 30, "e", "f" CSV <<-CSV ] 40, "a", "b" 50, "c", "d" 60, "e", "f" CSV
Although, this looks pretty scary, its again valid Ruby syntax. As many other languages Ruby allows a comma in front of the closing square bracket. We can use this to pretty up this construct and to make it more readable:
CHUNKS = [ <<-CSV , 10, "a", "b" 20, "c", "d" 30, "e", "f" CSV <<-CSV , 40, "a", "b" 50, "c", "d" 60, "e", "f" CSV ]
The following also works, and looks nicer, I think:
ReplyDeleteCHUNKS = [<<-CSV1, <<-CSV2]
10, "a", "b"
20, "c", "d"
30, "e", "f"
CSV1
40, "a", "b"
50, "c", "d"
60, "e", "f"
CSV2