2012-05-09 65 views
165

Niedawno zdecydowałem się w mojej pracy na przewodnik w stylu ruby. Jednym z edyktów jest to, że żadna z linii nie powinna być szersza niż 80 znaków. Ponieważ jest to projekt Rails, często mamy ciągi, które są nieco dłuższe - tzn. "Użytkownik X chciał wysłać ci wiadomość o Thing Y", która nie zawsze mieści się w granicach 80 znaków.Łamanie długich ciągów na wielu liniach w Ruby bez zdzierania nowych linii

I rozumie są trzy sposoby mają długi okres ciąg wielu linii:

  • heredoc
  • %} P {
  • Łańcuch znaków konkatenacji.

Jednak wszystkie te przypadki w końcu zabierają więcej cykli obliczeniowych, co wydaje się głupie. Łączenie ciągów oczywiście, ale dla HEREDOC i% Q muszę rozebrać nowe linie, przez coś takiego jak .gsub (/ \ n $ /, '').

Czy jest to metoda czysto składni, która jest równoważna po prostu cały ciąg w jednym wierszu? Celem jest oczywiście nie wydawanie żadnych dodatkowych cykli tylko dlatego, że chcę, aby mój kod był nieco bardziej czytelny. (Tak, zdaję sobie sprawę, że trzeba zrobić, że kompromis dużo ... ale dla długości łańcucha, to po prostu wydaje się głupie.)

Aktualizacja: Odwrotne ukośniki nie są dokładnie to, co chcę, bo tracisz wcięcia, które rzeczywiście wpływa na styl/czytelność.

Przykład:

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

znajdę wyżej trochę trudne do odczytania.

EDIT: Dodałem odpowiedź poniżej; trzy lata później mamy teraz krętą dziedzinę.

+0

Może warto poświęcić chwilę na czynnik z tych ciągów. – Cheezmeister

+4

możliwy duplikat [Ruby: Czy mogę napisać wieloliniowy ciąg bez konkatenacji?] (Http://stackoverflow.com/questions/2337510/ruby-can-can-i-write-multi-line-string-with-no- konkatenacja) – givanse

+0

Nie jest jasne, czy chcesz zachować znaki "\ n" nowej linii, czy nie. Górna odpowiedź ich nie zachowuje, ale twoja odpowiedź brzmi. Pytanie brzmi "bez obnażania nowych linii" - tak, jak mówi opis "[...] muszę rozebrać nowe linie". –

Odpowiedz

22

Trzy lata później w Ruby 2.3 pojawiło się rozwiązanie: krętacki heredok.

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 Link postu: https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredoc

wcięcia najsłabiej wcięte linii będą usunięto z każdej linii treści.

+9

Dla każdego, kto zastanawia się: '<< ~ HEREDOC' zachowuje znaki nowej linii, to tylko pozbywa się wcięć. Na przykład. 'line 1 \ nline 2 \ nline 3 \ n' –

+0

Rozbiórka newlines będzie nadal wymagać dodatkowych obliczeń, co nie było pożądane w rodzaju PO. – henrebotha

43

Możesz użyć \, aby wskazać, że jakakolwiek linia Ruby będzie kontynuowana w następnej linii. Działa to ze strunami też:

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

puts string.inspect 

wyjście wola "this is a string that spans lines"

+9

huh. to całkiem proste. cóż, to chyba zbyt wiele, żeby o to zapytać, ale nie mogę podać następnej linii. Byłoby idealnie, gdybym mógł go dopasować do znaku równości. – chug2k

+3

Uwaga: po tym ukośniku odwrotnym nie można mieć spacji. To musi być ostatnia postać. –

+1

Zobacz odpowiedź @Jsesehz. Sposób na ładnie sformatowany kod z odpowiednim wcięciem polega na umieszczeniu każdej linii w cudzysłowach. – orrd

325

Może to jest to, czego szukasz?

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

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

huh. tak, to całkiem idealne. czy to faktycznie robi konkatenację pod maską? (ukrywając +?) – chug2k

+10

Jestem prawie pewien, że nie jest; Próbowałem zarówno undef'ing i przedefiniowanie String # + i nie wydaje się, aby coś było tam wysyłane. – Jessehz

+0

Również umieszczanie łańcuchów obok siebie na tej samej linii również działa, ale to nie jest zbyt użyteczne. – Jessehz

6

Miałem ten problem, gdy próbuję napisać bardzo długi URL, następujące utwory.

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 

Uwaga: nie może być żadnych nowych linii, białych spacji, gdy tworzony jest ciąg url. Jeśli chcesz nowych linii, użyj HEREDOC.

Tutaj masz wcięcia dla czytelności, łatwości modyfikacji, bez skrzypiących cytatów i odwrotnych ukośników na każdej linii. Koszt dołączenia do ciągów powinien być nieistotny.

2

I zmodyfikowana odpowiedź Zacka odkąd chciał spacje i interpolacji, ale nie newlines i używane:

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

gdzie name = 'fred' ten produkuje It's a nice day "fred" for a walk!

Powiązane problemy