2012-05-09 12 views
165

Recientemente decidimos en mi trabajo una guía de estilo Ruby. Uno de los edictos es que ninguna línea debe tener más de 80 caracteres. Como este es un proyecto de Rails, a menudo tenemos cadenas que son un poco más largas, es decir, "El usuario X quería enviarle un mensaje sobre la cosa Y" que no siempre encaja dentro del límite de 80 caracteres.Descomponer cadenas largas en varias líneas en Ruby sin eliminar líneas nuevas

entiendo que hay tres maneras de tener un lapso de cadena larga: varias líneas

  • heredoc
  • % Q} {
  • real concatenación de cadenas.

Sin embargo, todos estos casos terminan tomando más ciclos de computación, lo que parece una tontería. Concatenación de cadenas obviamente, pero para HEREDOC y% Q tengo que eliminar las nuevas líneas, a través de algo como .gsub (/ \ n $ /, '').

¿Hay una forma de sintaxis pura para hacer esto, que es equivalente a simplemente tener toda la cadena en una línea? El objetivo es, obviamente, no gastar ningún ciclo extra solo porque quiero que mi código sea un poco más legible. (Sí, me doy cuenta de que tienes que cambiar mucho esa diferencia ... pero para la longitud de la cadena, esto parece tonto.)

Actualización: Las barras diagonales inversas no son exactamente lo que quiero porque pierdes sangría, lo que realmente afecta el estilo/legibilidad

Ejemplo:

if foo 
    string = "this is a \ 
string that spans lines" 
end 

me parece lo anterior un poco difícil de leer.

EDIT: He añadido una respuesta a continuación; tres años más tarde ahora tenemos el squiggly heredoc.

+0

Puede ser que valga la pena objeto de eliminar esas cadenas. – Cheezmeister

+4

posible duplicado de [Ruby: ¿Puedo escribir cadenas de múltiples líneas sin concatenación?] (Http://stackoverflow.com/questions/2337510/ruby-can-i-write-multi-line-string-with-no- concatenación) – givanse

+0

No está claro si desea mantener '\ n' los caracteres de nueva línea o no. La respuesta principal no los mantiene, pero tu respuesta sí. La pregunta dice "sin quitar las nuevas líneas", pero la descripción dice "[...] Tengo que quitar las nuevas líneas". –

Respuesta

22

Tres años después, ahora hay una solución en Ruby 2.3: The squiggly heredoc.

class Subscription 
    def warning_message 
    <<~HEREDOC 
     Subscription expiring soon! 
     Your free trial will expire in #{days_until_expiration} days. 
     Please update your billing information. 
    HEREDOC 
    end 
end 

Blog enlace mensaje: https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredoc

El sangrado de la línea-menos sangría será eliminó de cada línea de los contenidos.

+9

Para cualquier otra persona que se pregunte: '<< ~ HEREDOC' conserva los caracteres de nueva línea, solo elimina la sangría. P.ej. 'line 1 \ nline 2 \ nline 3 \ n' –

+0

Sin embargo, la eliminación de nuevas líneas requerirá un cálculo adicional, que el tipo OP implícito no era deseable. – henrebotha

43

Puede usar \ para indicar que cualquier línea de Ruby continúa en la siguiente línea. Esto funciona con cuerdas demasiado:

string = "this is a \ 
string that spans lines" 

puts string.inspect 

es la salida "this is a string that spans lines"

+9

huh. eso es bastante simple. Bueno, probablemente sea demasiado pedir, pero no puedo sangrar la siguiente línea. sería ideal si pudiera emparejarlo con el signo igual. – chug2k

+3

Nota: no puede tener ningún espacio en blanco después de esa barra invertida. Debe ser el último personaje. –

+1

Ver la respuesta por @Jessehz. La forma de tener un código muy formateado con sangría adecuada es poner cada línea entre comillas. – orrd

325

Tal vez esto es lo que está buscando?

string = "line #1"\ 
     "line #2"\ 
     "line #3" 

p string # => "line #1line #2line #3" 
+2

huh. sí, eso es bastante perfecto. ¿Es eso realmente hacer una concatenación debajo del capó? (¿Oculto un +?) – chug2k

+10

Estoy bastante seguro de que no lo es; Probé tanto para descifrar como para redefinir String # + y no parece que se envíe nada allí. – Jessehz

+0

Además, poner las cuerdas una al lado de la otra en la misma línea también funciona, pero eso no es muy útil. – Jessehz

6

Tuve este problema cuando trato de escribir una url muy larga, el siguiente funciona.

image_url = %w(
    http://minio.127.0.0.1.xip.io:9000/ 
    bucket29/docs/b7cfab0e-0119-452c-b262-1b78e3fccf38/ 
    28ed3774-b234-4de2-9a11-7d657707f79c? 
    X-Amz-Algorithm=AWS4-HMAC-SHA256& 
    X-Amz-Credential=AJAKJFAFGAKAJDDAF 
    %2Fus-east-1%2Fs3%2Faws4_request& 
    X-Amz-Date=20170702T000940Z& 
    X-Amz-Expires=3600&X-Amz-SignedHeaders=host& 
    X-Amz-Signature=QEWKJRQJEWR813247812347FKFS 
    KQWREJQ3108418324732o45o1324kldsfjasf 
).join 

Nota, no debe haber ningún saltos de línea, espacios en blanco cuando se forma la cadena URL. Si desea nuevas líneas, entonces use HEREDOC.

Aquí tiene sangría para legibilidad, facilidad de modificación, sin las comillas y las barras invertidas en todas las líneas. El costo de unirse a las cadenas debe ser insignificante.

2

que modifica la respuesta de Zack desde que quería espacios y la interpolación, pero no saltos de línea y usados:

%W[ 
    It's a nice day "#{name}" 
    for a walk! 
].join(' ') 

donde name = 'fred' Esto produce It's a nice day "fred" for a walk!

Cuestiones relacionadas