रूबी में कई लाइनों पर लंबे स्ट्रिंग्स को तोड़कर बिना न्यूलाइड स्ट्रिपिंग के


221

हमने हाल ही में अपनी नौकरी पर रूबी स्टाइल गाइड का फैसला किया। एडिट्स में से एक यह है कि कोई भी रेखा 80 वर्णों से अधिक व्यापक नहीं होनी चाहिए। चूँकि यह एक रेल परियोजना है, हमारे पास अक्सर ऐसे तार होते हैं जो थोड़े लंबे होते हैं - यानी " उपयोगकर्ता X आपको थिंग वाई के बारे में एक संदेश भेजना चाहता था " जो हमेशा 80 वर्ण शैली की सीमा के भीतर फिट नहीं होता है।

मैं समझता हूं कि एक लंबी स्ट्रिंग अवधि के तीन तरीके हैं कई लाइनें:

  • हियरडॉक
  • % क्यू {}
  • वास्तविक स्ट्रिंग संघनन।

हालांकि, इन सभी मामलों में अंत में अधिक संगणना चक्र होता है, जो मूर्खतापूर्ण लगता है। स्ट्रिंग कॉन्सेप्टन स्पष्ट रूप से, लेकिन इसके लिए HEREDOCऔर %Qमुझे कुछ की तरह, नई सुर्खियों को छीनना होगा .gsub(/\n$/, '')

क्या ऐसा करने के लिए एक शुद्ध वाक्यविन्यास तरीका है, जो केवल एक पंक्ति पर पूरे स्ट्रिंग होने के बराबर है? लक्ष्य, जाहिर है, कोई अतिरिक्त चक्र खर्च नहीं करने के लिए, क्योंकि मैं चाहता हूं कि मेरा कोड थोड़ा अधिक पठनीय हो। (हां, मुझे एहसास है कि आपको उस ट्रेडऑफ़ को बहुत अधिक करना होगा ... लेकिन स्ट्रिंग की लंबाई के लिए, यह सिर्फ मूर्खतापूर्ण लगता है।)

अपडेट: बैकस्लैश ठीक वही नहीं हैं जो मैं चाहता हूं क्योंकि आप इंडेंटेशन खो देते हैं, जो वास्तव में शैली / पठनीयता को प्रभावित करता है।

उदाहरण:

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

मुझे ऊपर पढ़ने में थोड़ा मुश्किल लगता है।

संपादित करें : मैंने नीचे एक उत्तर जोड़ा; तीन साल बाद अब हमारे पास स्क्वीजीली हेरेडोक है।


यह उन तार बाहर कारक के लिए अपने लायक हो सकता है।
शेजमिस्टर


Whether यह स्पष्ट नहीं है कि आप \nन्यूलाइन वर्ण रखना चाहते हैं या नहीं। शीर्ष उत्तर उन्हें नहीं रखता है - फिर भी आपका उत्तर देता है। सवाल कहता है, "नई स्ट्रिपिंग के बिना" - विवरण में कहा गया है "[...] मुझे नए सिरे से स्ट्रिप आउट करना है।"
ब्रायन डिमास

जवाबों:


432

शायद यह वही है जो आप खोज रहे हैं?

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

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

4
हुह। हाँ, यह बहुत सही है। यह वास्तव में हुड के नीचे एक समतल कर रहा है? (छुपकर ए +?)
chug2k

13
मुझे पूरा यकीन है कि यह नहीं है; मैंने दोनों को अपरिभाषित करने की कोशिश की और स्ट्रिंग # को फिर से परिभाषित किया और ऐसा नहीं लगता कि कुछ भी वहां भेजा जा रहा है।
जेसिह

इसके अलावा, एक ही लाइन पर एक दूसरे के बगल में तार लगाने से भी काम होता है, लेकिन यह बहुत उपयोगी नहीं है।
जेसीज

3
मुझे एमिली का समाधान भी पसंद है। लेकिन किसी कारण से मैं इसके साथ अधिक सहज हूं क्योंकि निम्नलिखित तर्ज पर प्रमुख सफेद रिक्त स्थान दूसरे के बिना अनुमान लगाया जा सकता है।
अमीन एरियाना

5
पुनः सम्‍मिलित करें, इस संबंधित प्रश्‍न के लिए अमदन के उत्तर की जाँच करें । वह बाईटेकोड का उपयोग यह साबित करने के लिए करता है कि यह तारों को समतल नहीं कर रहा है, लेकिन उन्हें एक लंबे समय तक एक ही मान रहा है।
टॉम हुंड्ट

55

आप यह \इंगित करने के लिए उपयोग कर सकते हैं कि रूबी की कोई भी रेखा अगली पंक्ति पर जारी है। यह तार के साथ भी काम करता है:

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

puts string.inspect

उत्पादन होगा "this is a string that spans lines"


11
हुह। यह बहुत आसान है। खैर, यह शायद पूछने के लिए बहुत अधिक है, लेकिन मैं अगली पंक्ति का संकेत नहीं दे सकता। अगर मैं इसे बराबरी के संकेत के साथ मिला सकता हूं तो यह आदर्श होगा।
chug2k

5
नोट: आपके पास उस बैकस्लैश के बाद कोई भी सफेद स्थान नहीं हो सकता है। यह अंतिम चरित्र होना चाहिए।
जूलियन मान

3
@Jessehz द्वारा उत्तर देखें। उचित रूप से इंडेंटिंग के साथ अच्छी तरह से स्वरूपित कोड रखने का तरीका प्रत्येक पंक्ति को उद्धरण में रखना है।
orrd

36

तीन साल बाद, अब रूबी 2.3 में एक समाधान है: स्क्विगली हेरेडोक।

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

ब्लॉग पोस्ट लिंक: https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredoc

सामग्री की प्रत्येक पंक्ति से सबसे कम-इंडेंटेड लाइन का इंडेंटेशन हटा दिया जाएगा।


29
किसी और के लिए सोच: <<~HEREDOCNewline वर्ण रखता है, यह केवल इंडेंटेशन के छापे। उदाline 1\nline 2\nline 3\n
ब्रायन डिमास

1
स्ट्रिपिंग न्यूलाइन्स को अभी भी अतिरिक्त गणना की आवश्यकता होगी, हालांकि, जिसका अर्थ है कि ओपी की तरह वांछनीय नहीं था।
हेनरेबोथा

1
@henrebotha हां, लेकिन ओपी ने और अधिक स्पष्ट रूप से कहा कि वे "केवल एक लाइन पर पूरे स्ट्रिंग होने के बराबर" चाहते हैं, जिसके लिए कोई नई सीमा नहीं होनी चाहिए।
निक

तो आपने अपने प्रश्न में स्पष्ट रूप से कहा है कि आप एक हेरेडोक का उपयोग नहीं करना चाहते थे और नई रूपरेखाओं को अलग करना चाहते थे। यहां आपका जवाब एक हेरेडोक का उपयोग करता है और आपको "पोस्ट-प्रोसेसिंग" से बचने की आवश्यकता है।
लैमोंट

17

मुझे यह समस्या तब हुई जब मैंने एक बहुत लंबी यूआरएल लिखने की कोशिश की, निम्नलिखित काम करता है।

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=ABABABABABABABABA
    %2Fus-east-1%2Fs3%2Faws4_request&
    X-Amz-Date=20170702T000940Z&
    X-Amz-Expires=3600&X-Amz-SignedHeaders=host&
    X-Amz-Signature=ABABABABABABABABABABAB
    ABABABABABABABABABABABABABABABABABABA
).join

ध्यान दें, url स्ट्रिंग के बनने पर कोई भी नया अंक, सफेद स्थान नहीं होना चाहिए। यदि आप नई सूची चाहते हैं, तो HEREDOC का उपयोग करें।

यहाँ आपको पठनीयता, संशोधन में आसानी, हर पंक्ति में फ़िज़ूल उद्धरण और बैकस्लैश के बिना इंडेंटेशन है। तार जुड़ने की लागत नगण्य होनी चाहिए।


10

मैंने ज़ैक के उत्तर को संशोधित किया क्योंकि मैं रिक्त स्थान और प्रक्षेप चाहता था लेकिन नई रूपरेखा और उपयोग नहीं किया गया था:

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

जहाँ name = 'fred'यह उत्पादन होता हैIt's a nice day "fred" for a walk!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.