Ruby: ¿Puedo escribir cadenas multilíneas sin concatenación?
¿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'
Como, ¿hay una manera de implicar concatenación?
13 answers
Hay partes de esta respuesta que me ayudaron a obtener lo que necesitaba (concatenación de múltiples líneas SIN espacios en blanco adicionales), 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 bono, aquí hay una versión que usa la sintaxis divertida de HEREDOC (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"
Este ú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 w. r. t. la cadena (es decir, delante de él, pero usando métodos de instancia que generalmente 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), necesitará usar la sintaxis con guiones (es decir, p <<-END_SQL
en lugar de p <<END_SQL
). De lo contrario, el espacio en blanco de sangría hace que el identificador se interprete como una continuación de la cadena.
Esto no ahorra mucho escribiendo, pero se ve mejor que usar signos+, para me.
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"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-02 19:35:03
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 puede 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-25 09:42:29
En ruby 2.0 ahora puedes usar %
Por ejemplo:
SQL = %{
SELECT user, name
FROM users
WHERE users.id = #{var}
LIMIT #{var2}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-28 01:33:51
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 multilínea comienza con %q, seguida de un {, [ o (, y luego termina con el carácter invertido correspondiente. %q no permite la interpolación; %Q lo hace para que pueda escribir cosas como esta:
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íneas, así que llamémoslas multilíneas Perl.
Tenga en cuenta, sin embargo, que si si usas Perl multilines o heredocs como Mark y Peter han sugerido, terminarás con espacios en blanco potencialmente innecesarios. Tanto en mis ejemplos como en sus ejemplos, las líneas "from" y "where" contienen espacios en blanco iniciales debido a su sangría en el código. Si no desea este espacio en blanco, debe usar cadenas concatenadas como lo está haciendo ahora.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-26 09:13:42
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-16 06:57:19
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-25 20:51:13
También puede usar tres comillas dobles
x = """
this is
a multiline
string
"""
2.3.3 :012 > x
=> "\nthis is\na multiline\nstring\n"
Si es necesario eliminar los saltos de línea "\n" use la barra invertida "\" al final de cada línea
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-20 23:48:05
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-28 19:03:29
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'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-25 20:52:55
Si hace mente espacios adicionales y 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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-12 22:09:53
Recientemente con las nuevas características 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 usar esto combinado con el .squish
le permitirá escribir multilínea de 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-01 11:42:08
conn.exec [
"select attr1, attr2, attr3, ...",
"from table1, table2, table3, ...",
"where ..."
].join(' ')
Esta sugerencia tiene la ventaja aquí-documentos y cadenas largas que los indentadores automáticos pueden sangrar cada parte de la cadena apropiadamente. Pero tiene un costo de eficiencia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-25 21:10:16
Para evitar cerrar los paréntesis para 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"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-15 16:34:36