रुबी के पास असली स्ट्रिंगबफर या स्ट्रिंगियो क्यों नहीं है?

मैंने हाल ही में एक अच्छा पोस्ट पढ़ा है रुबी में StringIO का उपयोग करना। लेखक का उल्लेख नहीं है, हालांकि, यह है कि StringIO सिर्फ एक "I." है। कोई "ओ" नहीं है आप नहीं कर सकते ऐसा करते हैं, उदाहरण के लिए:

s = StringIO.new
s << 'foo'
s << 'bar'
s.to_s
# => should be "foo\nbar"
# => really is ''`

रुबी को वास्तव में एक जावा की तरह स्ट्रिंगबफर की आवश्यकता होती है। स्ट्रिंगबफर दो महत्वपूर्ण उद्देश्यों की सेवा करते हैं। सबसे पहले, वे आपको रुबी के स्ट्रिंगियो के आउटपुट आधे का परीक्षण करने देते हैं। दूसरा, वे छोटे हिस्सों से लंबे तारों के निर्माण के लिए उपयोगी हैं - जोएल जो हमें बार-बार याद दिलाता है वह अन्यथा बहुत धीमा है।

क्या कोई अच्छा प्रतिस्थापन है?

यह सच है कि रूबी में स्ट्रिंग्स म्यूटेबल हैं, लेकिन इसका मतलब यह नहीं है कि हमें हमेशा उस कार्यक्षमता पर भरोसा करना चाहिए। यदि सामान बड़ा है, तो इसका प्रदर्शन और स्मृति आवश्यकताएं, उदाहरण के लिए, वास्तव में खराब है।

result = stuff.map(&:to_s).join(' ')

जावा में ऐसा करने का "सही" तरीका है:

result = StringBuffer.new("")
for(String s : stuff) {
  result.append(s);
}

हालांकि मेरा जावा थोड़ा जंगली है।

0
ro fr bn
आपकी स्ट्रिंग में शामिल होने वाला उदाहरण जावा कोड के बराबर नहीं है। जैसा कि आप उल्लेख करते हैं, रुबी स्ट्रिंग्स म्यूटेबल हैं, इसलिए रूबी में आप बस करते हैं: stuff.inject ('') {| res, s | res << s.to_s} । आप सुरक्षित रूप से रूबी स्ट्रिंग्स पर भरोसेमंद होने पर भरोसा कर सकते हैं, यह बदलने वाला नहीं है क्योंकि यह अस्तित्व में प्रत्येक रूबी एप्लिकेशन को तोड़ देगा।
जोड़ा लेखक Theo, स्रोत
मेगा नौकरानी को बदनामी से छुटकारा पाने से संपार्श्विक क्षति के रूप में हटा दिया गया है।
जोड़ा लेखक Andrew Grimm, स्रोत
मैं वास्तव में समझ में नहीं आता क्यों स्ट्रिंगियो के पास to_s विधि नहीं है। यह एक वर्ग है जो एक स्ट्रिंग का प्रबंधन करता है, इसलिए यदि आप उस स्ट्रिंग को चाहते हैं तो आपको विशेष रूप से इसके लिए पूछना होगा। रूबी सम्मेलन के बाद से यह to_s विधि होनी चाहिए, लेकिन ऐसा नहीं है। (अगर मैं गलत हूं तो कोई मुझे सही कर सकता है)
जोड़ा लेखक hcarreras, स्रोत
"मेगा नौकरानी?" उसके बारे में कभी नहीं सुना। स्ट्रिंगबफर में कभी भी विश्वास नहीं किया गया था, लेकिन मैंने हमेशा उन्हें अपना कोड देखने वाले किसी के डर के लिए इस्तेमाल किया। लेकिन वास्तव में, क्या वह सामान कभी भी जोड़ता है?
जोड़ा लेखक Dan Rosenstark, स्रोत
शायद एक 'स्पेसबॉल्स' संदर्भ।
जोड़ा लेखक Stephen Eilert, स्रोत
@Theo रूबी 3 में, स्ट्रिंग अक्षर अपरिवर्तनीय होगा। हालांकि हम अभी भी mutable String.new या + ''
जोड़ा लेखक Franklin Yu, स्रोत

5 उत्तर

खैर, एक स्ट्रिंगबफर रूबी में काफी जरूरी नहीं है, मुख्य रूप से क्योंकि रुबी में स्ट्रिंग्स म्यूटेबल हैं ... इस प्रकार आप प्रत्येक कंसट के साथ नए स्ट्रिंग बनाने के बजाय मौजूदा स्ट्रिंग को संशोधित करके एक स्ट्रिंग बना सकते हैं।

एक नोट के रूप में, आप विशेष स्ट्रिंग सिंटैक्स का भी उपयोग कर सकते हैं जहां आप एक स्ट्रिंग बना सकते हैं जो स्ट्रिंग के भीतर अन्य चरों का संदर्भ देता है, जो बहुत पठनीय स्ट्रिंग निर्माण के लिए बनाता है। विचार करें:

first = "Mike"
last = "Stone"
name = "#{first} #{last}"

इन तारों में अभिव्यक्ति भी हो सकती है, केवल चर नहीं ... जैसे कि:

str = "The count will be: #{count + 1}"
count = count + 1
0
जोड़ा
यह निश्चित रूप से सच है, और यह छोटे इंटरपोलेशंस के लिए बहुत अच्छा है। हालांकि, एचटीएमएल पृष्ठों जैसे लंबे तारों के निर्माण के लिए यह लुभावना है। en.wikipedia.org/wiki/Schlemiel_the_painter%27s_Algorithm देखें
जोड़ा लेखक James A. Rosen, स्रोत
निश्चित रूप से, लेकिन HTML पृष्ठों के निर्माण के लिए, उस फ़ंक्शन के लिए कुछ ऐसा क्यों न करें जो एचएएमएल या ईआरबी की तरह है?
जोड़ा लेखक Earl Jenkins, स्रोत
पुन: "श्लेमेल द पेंटर के एल्गोरिदम" यदि आप उपरोक्त में स्ट्रिंगियो का उपयोग कर रहे हैं, तो जोएल स्पॉल्स्की की आलोचना लागू नहीं होती है। स्ट्रिंगियो के पास फ़ाइल की तरह एक खोज सूचक है। हर बार स्ट्रिंग के अंत को दोबारा बदलने की जरूरत नहीं है। और लंबे तारों के लिए आप% {} या एक लाइब्रेरी का उपयोग कर सकते हैं जैसे अर्ल ने सुझाव दिया है।
जोड़ा लेखक CJ., स्रोत

I looked at the ruby documentation for StringIO, and it looks like what you want is StringIO#string, not StringIO#to_s

इस प्रकार, अपना कोड इस पर बदलें:

s = StringIO.new
s << 'foo'
s << 'bar'
s.string
0
जोड़ा

आपका उदाहरण रुबी में काम करता है - मैंने अभी कोशिश की है।

irb(main):001:0> require 'stringio'
=> true
irb(main):002:0> s = StringIO.new
=> #
irb(main):003:0> s << 'foo'
=> #
irb(main):004:0> s << 'bar'
=> #
irb(main):005:0> s.string
=> "foobar"

Unless I'm missing the reason you're using to_s - that just outputs the object id.

0
जोड़ा

I did some benchmarks and the fastest approach is using the String#<< method. Using StringIO is a little bit slower.

s = ""; Benchmark.measure{5000000.times{s << "some string"}}
=>   3.620000   0.100000   3.720000 (  3.970463)

>> s = StringIO.new; Benchmark.measure{5000000.times{s << "some string"}}
=>   4.730000   0.120000   4.850000 (  5.329215)

स्ट्रिंग # + विधि का उपयोग करके तारों को जोड़ना परिमाण के कई आदेशों द्वारा सबसे धीमा दृष्टिकोण है:

>> s = ""; Benchmark.measure{10000.times{s = s + "some string"}}
=>   0.700000   0.560000   1.260000 (  1.420272)

>> s = ""; Benchmark.measure{10000.times{s << "some string"}}
=>   0.000000   0.000000   0.000000 (  0.005639)

So I think the right answer is that the equivalent to Java's StringBuffer is simply using String#<< in Ruby.

0
जोड़ा
क्या होता है यदि आप कुछ अक्षरों को बहुत लंबी स्ट्रिंग में जोड़ना चाहते हैं? मुझे लगता है <कोड> स्ट्रिंगियो तो तेज़ होगा
जोड़ा लेखक nothing-special-here, स्रोत
यहाँ मेरे दिमाग को उड़ाने का तरीका।
जोड़ा लेखक drewish, स्रोत
और क्या होता है जब रूबी तारों को अपरिवर्तनीय बनाता है? इस तरह के सूक्ष्म अनुकूलन अंत में एक नरक हैं।
जोड़ा लेखक akostadinov, स्रोत
इस बेंचमार्क के लिए रूबी का किस संस्करण का उपयोग किया गया था, कृपया?
जोड़ा लेखक Jared Beck, स्रोत
वाह। इसलिए यह सही जवाब होना चाहिए क्योंकि स्ट्रिंग सबसे तेज़ है। रूबी 2.1.5 और एक ही परिणाम पर परीक्षण किया।
जोड़ा लेखक Nikkolasg, स्रोत

रुबी में अन्य आईओ-प्रकार की वस्तुओं की तरह, जब आप आईओ को लिखते हैं, तो चरित्र सूचक आगे बढ़ता है।

>> s = StringIO.new
=> #
>> s << 'foo'
=> #
>> s << 'bar'
=> #
>> s.pos
=> 6
>> s.rewind
=> 0
>> s.read
=> "foobar"

Another way to skin this cat.

0
जोड़ा
मुझे वास्तव में आवश्यकता नहीं है क्योंकि यह स्ट्रिंगियो # पढ़ा गया है, लेकिन मैं हमेशा कुछ करने के लिए एक से अधिक तरीके जानने का प्रशंसक हूं। +1
जोड़ा लेखक James A. Rosen, स्रोत
अहम, मेरा मतलब <कोड> स्ट्रिंगियो # स्ट्रिंग था
जोड़ा लेखक James A. Rosen, स्रोत