linea - manejo de cadenas en ruby
Ruby: ¿Puedo escribir cadenas de varias líneas sin concatenación? (13)
A veces vale la pena eliminar nuevos caracteres de línea /n
como:
conn.exec <<-eos.squish
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
¿Hay alguna manera de hacer que esto se vea un poco mejor?
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''
Al igual que, ¿hay una manera de implicar la concatenación?
En ruby 2.0 ahora puedes usar %
Por ejemplo:
SQL = %{
SELECT user, name
FROM users
WHERE users.id = #{var}
LIMIT #{var2}
}
Hay múltiples sintaxis para cadenas de varias líneas como ya ha leído. Mi favorito es el estilo Perl:
conn.exec %q{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}
La cadena de varias líneas comienza con% q, seguido de un {, [o (, y luego termina con el carácter invertido correspondiente.% Q no permite la interpolación;% Q sí lo hace, así que puede escribir cosas como estas:
conn.exec %Q{select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from #{table_names},
where etc etc etc etc etc etc etc etc etc etc etc etc etc}
En realidad no tengo idea de cómo se llaman estos tipos de cadenas multilínea, así que llamémosles multilínea Perl.
Sin embargo, tenga en cuenta que ya sea que use Perl multilines o heredocs como Mark y Peter han sugerido, terminará con espacios en blanco potencialmente innecesarios. Tanto en mis ejemplos como en sus ejemplos, las líneas "de" y "donde" contienen espacios en blanco iniciales debido a su sangría en el código. Si no se desea este espacio en blanco, debe usar cadenas concatenadas como lo está haciendo ahora.
Hay piezas en esta respuesta que me ayudaron a obtener lo que necesitaba (concatenación multilínea SIN espacio en blanco adicional), pero como ninguna de las respuestas reales lo tenía, las estoy compilando aquí:
str = ''this is a multi-line string''/
'' using implicit concatenation''/
'' to prevent spare /n/'s''
=> "this is a multi-line string using implicit concatenation to eliminate spare
//n''s"
Como beneficio adicional, aquí hay una versión que usa la sintaxis HEREDOC divertida (a través de este enlace ):
p <<END_SQL.gsub(//s+/, " ").strip
SELECT * FROM users
ORDER BY users.id DESC
END_SQL
# >> "SELECT * FROM users ORDER BY users.id DESC"
Lo último sería principalmente para situaciones que requieren más flexibilidad en el procesamiento. Personalmente no me gusta, pone el procesamiento en un lugar extraño y la cadena (es decir, delante de él, pero utilizando métodos de instancia que normalmente vienen después), pero está ahí. Tenga en cuenta que si está sangrando el último identificador END_SQL
(que es común, ya que probablemente esté dentro de una función o módulo), deberá usar la sintaxis con guión (es decir, p <<-END_SQL
lugar de p <<END_SQL
) . De lo contrario, el espacio en blanco con sangría hace que el identificador se interprete como una continuación de la cadena.
Esto no ahorra mucho al escribir, pero a mi me parece mejor que usar signos +.
EDITAR: Añadiendo uno más:
p %{
SELECT * FROM users
ORDER BY users.id DESC
}.gsub(//s+/, " ").strip
# >> "SELECT * FROM users ORDER BY users.id DESC"
Otras opciones:
#multi line string
multiline_string = <<EOM
This is a very long string
that contains interpolation
like #{4 + 5} /n/n
EOM
puts multiline_string
#another option for multiline string
message = <<-EOF
asdfasdfsador #{2+2} this month.
asdfadsfasdfadsfad.
EOF
puts message
Para evitar cerrar los paréntesis de cada línea, simplemente puede usar comillas dobles con una barra invertida para escapar de la nueva línea:
"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"
Recientemente, con las nuevas funciones de Ruby 2.3, el nuevo squiggly HEREDOC
le permitirá escribir nuestras cadenas multilínea de una manera agradable con un cambio mínimo, por lo que el uso combinado de .squish
le permitirá escribir .squish
una manera agradable.
[1] pry(main)> <<~SQL.squish
[1] pry(main)* select attr1, attr2, attr3, attr4, attr5, attr6, attr7
[1] pry(main)* from table1, table2, table3, etc, etc, etc, etc, etc,
[1] pry(main)* where etc etc etc etc etc etc etc etc etc etc etc etc etc
[1] pry(main)* SQL
=> "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"
ref: https://infinum.co/the-capsized-eight/multiline-strings-ruby-2-3-0-the-squiggly-heredoc
Sí, si no te importa que se inserten nuevas líneas adicionales:
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''
Alternativamente puedes usar un heredoc :
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
Si le importan los espacios adicionales y las nuevas líneas, puede utilizar
conn.exec %w{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} * '' ''
(use% W para cadenas interpoladas)
También puedes usar comillas dobles.
x = """
this is
a multiline
string
"""
2.3.3 :012 > x
=> "/nthis is/na multiline/nstring/n"
Si es necesario para eliminar los saltos de línea "/ n" use la barra invertida "/" al final de cada línea
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''
<< es el operador de concatenación para cuerdas
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
conn.exec [
"select attr1, attr2, attr3, ...",
"from table1, table2, table3, ...",
"where ..."
].join('' '')
Esta sugerencia tiene la ventaja sobre los documentos de aquí y las cadenas largas que los sangradores automáticos pueden sangrar apropiadamente en cada parte de la cadena. Pero tiene un costo de eficiencia.