array - scan ruby example
¿Hay una manera fácil de hacer cadenas multilínea con sangría en Ruby? (4)
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo elimino los caracteres en blanco de Ruby HEREDOC? 11 respuestas
- Ruby sangría cuerdas multilínea [duplicar] 4 respuestas
Digamos que quería tener un bloque muy grande de código html bastante impreso en línea con mi código ruby. ¿Cuál es la forma más limpia de hacerlo sin perder ningún formato en mi cadena o tener que recordar algún tipo de expresión regular de gsub?
Codificar todo en una línea es fácil de hacer pero difícil de leer:
1.times do
# Note that the spaces have been changed to _ so that they are easy to see here.
doc = "/n<html>/n__<head>/n____<title>/n______Title/n____</title>/n__</head>/n__<body>/n____Body/n__</body>/n</html>/n"
ans = "Your document: %s" % [doc]
puts ans
end
El texto multilínea en ruby es más fácil de leer pero la cadena no se puede sangrar con el resto del código:
1.times do
doc = "
<html>
<head>
<title>
Title
</title>
</head>
<body>
Body
</body>
</html>
"
ans = "Your document: %s" % [doc]
puts ans
end
Por ejemplo, lo siguiente está sangrado con mi código, pero la cadena ahora tiene cuatro espacios adicionales delante de cada línea:
1.times do
doc = <<-EOM
<html>
<head>
<title>
Title
</title>
</head>
<body>
Body
</body>
</html>
EOM
ans = "Your document: %s" % [doc]
puts ans
end
La mayoría de la gente utiliza el código HEREDOC que se encuentra arriba y reemplaza las expresiones regulares en el resultado para eliminar los espacios en blanco adicionales al comienzo de cada línea. Me gustaría una forma en la que no tenga que pasar por la molestia de hacer una expresión cada vez.
Desde Ruby 2.3, el <<~
heredoc quita los espacios en blanco de contenido:
def make_doc(body)
<<~EOF
<html>
<body>
#{body}
</body>
</html>
EOF
end
puts make_doc(''hello'')
Para versiones anteriores de Ruby, lo siguiente es más detallado que las soluciones presentadas en las otras respuestas, pero casi no hay sobrecarga de rendimiento. Es casi tan rápido como un solo literal de cadena larga:
def make_doc(body)
"<html>/n" /
" <body>/n" /
" #{body}/n" /
" </body>/n" /
"</html>"
end
El "|" en YAML le permite crear cadenas multilínea que se pueden sangrar. El espacio en blanco solo se cuenta si está en columnas después del primer carácter que no es un espacio en blanco en la primera línea. De esta manera, puede tener una cadena multilínea que tiene sangría, pero también está sangrada en el código.
require ''yaml''
1.times do
doc = YAML::load(<<-EOM)
|
<html>
<head>
<title>
Title
</title>
</head>
<body>
Body
</body>
</html>
EOM
ans = "Your document: %s" % [doc]
puts ans
end
No es realmente obvio lo que estás pidiendo. Si quisiera generar cadenas como:
"when /n the/n clock/n strikes/n ten/n"
Sobre la marcha, los construiría dinámicamente:
%w[when the clock strikes ten].join("/n ")
=> "when/n the/n clock/n strikes/n ten"
Al concatenar un "/n"
final se agregará el retorno de carro final:
%w[when the clock strikes ten].join("/n ") + "/n"
=> "when/n the/n clock/n strikes/n ten/n"
Si estoy tratando con sub-cadenas que tienen espacios incrustados, ajustaría la matriz a:
[''when the'', ''clock strikes'', ''ten''].join("/n ") + "/n"
=> "when the/n clock strikes/n ten/n"
string = %q{This
is
indented
and
has
newlines}
Here hay un blog con algunos ejemplos de %q{}
, %Q{}
y otros.
En cuanto a que sea fácil de recordar, piense ''Q'' para las ''comillas''.
Nota al margen: Técnicamente no necesitas la ''q'' mientras haces la cita.
string = %{This
also
is indented
and
has
newlines
and handles interpolation like 1 + 1 = #{1+1}
}
Sin embargo, es una práctica recomendada y más legible utilizar %Q{}
.