The Ruby-way (TM) da Ruby 2.3: Usa il HEREDOC ondulato <<~
per definire una stringa multilinea con newline e rientro corretto:
conn.exec <<~EOS
select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc
where etc etc etc etc etc etc etc etc etc etc etc etc etc
EOS
# -> "select...\nfrom...\nwhere..."
Se il rientro corretto non è un problema, le virgolette singole e doppie possono comprendere più righe in Ruby:
conn.exec "select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc,
where etc etc etc etc etc etc etc etc etc etc etc etc etc"
# -> "select...\n from...\n where..."
Se le virgolette singole o doppie sono ingombranti perché ciò richiederebbe un sacco di escape, la notazione letterale della stringa percentuale %
è la soluzione più flessibile:
conn.exec %(select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc
where (ProductLine = 'R' OR ProductLine = "S") AND Country = "...")
# -> "select...\n from...\n where..."
Se lo scopo è quello di evitare le newline (che causeranno sia HEREDOC, virgolette e la stringa percentuale letterale), allora una continuazione di linea può essere usata inserendo una barra rovesciata \
come ultimo carattere non di spazi bianchi in una linea. Questo continuerà la linea e farà concatenare Ruby da una parte all'altra (fai attenzione agli spazi all'interno della stringa tra virgolette):
conn.exec 'select attr1, attr2, attr3, attr4, attr5, attr6, attr7 ' \
'from table1, table2, table3, etc, etc, etc, etc, etc, ' \
'where etc etc etc etc etc etc etc etc etc etc etc etc etc'
# -> "select...from...where..."
Se usi Rails String.squish
, toglierai la stringa di spazio iniziale e finale e comprimerai tutti gli spazi bianchi consecutivi (newline, tab e tutto) in un unico spazio:
conn.exec "select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc,
where etc etc etc etc etc etc etc etc etc etc etc etc etc".squish
# -> "select...attr7 from...etc, where..."
Più dettagli:
Sintassi di Ruby HEREDOC
La Here Document Notation for Strings funziona come un modo per designare lunghi blocchi di testo incorporati nel codice. Viene avviato <<
seguito da una stringa definita dall'utente (terminatore di fine stringa). Tutte le righe seguenti vengono concatenate fino a quando non viene trovato il terminatore End of String all'inizio di una riga:
puts <<HEREDOC
Text Text Text Text
Bla Bla
HEREDOC
# -> "Text Text Text Text\nBlaBla"
Il terminatore di End of String può essere scelto liberamente, ma è comune usare qualcosa come "EOS" (End of String) o qualcosa che corrisponde al dominio della String come "SQL".
HEREDOC supporta l' interpolazione per impostazione predefinita o quando il terminatore EOS è racchiuso tra virgolette doppie:
price = 10
print <<"EOS" # comments can be put here
1.) The price is #{price}.
EOS
# -> "1.) The price is 10."
L'interpolazione può essere disabilitata se il terminatore EOS è a virgoletta singola:
print <<'EOS' # Disabled interpolation
3.) The price is #{price}.
EOS
# -> "3.) The price is #{price}."
Una limitazione importante di <<HEREDOC
è che il terminatore End of String deve trovarsi all'inizio della riga:
puts <<EOS
def foo
print "foo"
end
EOS
EOS
#-> "....def foo\n......print "foo"\n....end\n..EOS
Per ovviare a questo, è <<-
stata creata la sintassi. Consente al rientro del terminatore EOS di rendere il codice più gradevole. Le linee tra il <<-
terminatore EOS e sono ancora utilizzate nella loro massima estensione, inclusi tutti i rientri:
puts <<-EOS # Use <<- to indent End of String terminator
def foo
print "foo"
end
EOS
# -> "..def foo\n....print "foo"\n..end"
Da Ruby 2.3, ora abbiamo l'HEREDOC che <<~
rimuove gli spazi bianchi principali:
puts <<~EOS # Use the squiggly HEREDOC <<~ to remove leading whitespace (since Ruby 2.3!)
def foo
print "foo"
end
EOS
# -> "def foo\n..print "foo"\nend"
Le righe vuote e le righe che contengono solo schede e spazio vengono ignorate da << ~
puts <<~EOS.inspect
Hello
World!
EOS
#-> "Hello\n..World!"
Se vengono utilizzate sia le schede che gli spazi, le schede vengono considerate uguali a 8 spazi. Se la riga meno rientrata si trova nel mezzo di una scheda, questa scheda non viene rimossa.
puts <<~EOS.inspect
<tab>One Tab
<space><space>Two Spaces
EOS
# -> "\tOne Tab\nTwoSpaces"
HEREDOC può fare cose folli come eseguire comandi usando i backtick:
puts <<`EOC`
echo #{price}
echo #{price * 2}
EOC
Le definizioni di stringa HEREDOC possono essere "impilate", il che significa che il primo terminatore EOS (EOSFOO in basso) terminerà la prima stringa e inizierà il secondo (EOSBAR in basso):
print <<EOSFOO, <<EOSBAR # you can stack them
I said foo.
EOSFOO
I said bar.
EOSBAR
Non penso che nessuno lo userebbe mai come tale, ma <<EOS
è davvero solo una stringa letterale e può essere messa ovunque una stringa possa essere normalmente messa:
def func(a,b,c)
puts a
puts b
puts c
end
func(<<THIS, 23, <<THAT)
Here's a line
or two.
THIS
and here's another.
THAT
Se non hai Ruby 2.3, ma Rails >=
3.0, puoi usare quello String.strip_heredoc
che fa lo stesso<<~
# File activesupport/lib/active_support/core_ext/string/strip.rb, line 22
class String
def strip_heredoc
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "".freeze)
end
end
puts <<-USAGE.strip_heredoc # If no Ruby 2.3, but Rails >= 3.0
This command does such and such.
Supported options are:
-h This message
...
USAGE
Letterali a percento
Vedere RubyDoc per come utilizzare il segno percentuale seguita da una stringa in parentesi accoppiare ad esempio una %(...)
, %[...]
, %{...}
, ecc o una coppia di carattere non alfanumerico come%+...+
Ultime parole
Infine, per ottenere la risposta alla domanda originale "Esiste un modo per implicare la concatenazione?" risposta: Ruby implica sempre la concatenazione se due stringhe (virgolette singole e doppie) vengono trovate back to back:
puts "select..." 'from table...' "where..."
# -> "select...from table...where..."
L'avvertenza è che questo non funziona attraverso le interruzioni di riga, perché Ruby sta interpretando una fine dell'istruzione e la conseguente linea di sole stringhe su una riga non fa nulla.