क्या आप किसी ऐसी वस्तु की तलाश कर रहे हैं जो IO
. की तरह व्यवहार करे ऑब्जेक्ट (फ़ाइलें, सॉकेट, आदि), लेकिन आप एक स्ट्रिंग की तरह नियंत्रित कर सकते हैं?
फिर StringIO
आपके लिए है।
मैं आपको कुछ उदाहरण और ध्यान देने योग्य बातें दिखाता हूँ!
बुनियादी उदाहरण
एक StringIO
create बनाने के लिए आपत्ति आप यह कर सकते हैं:
io = StringIO.new("abc")
फिर आप इस ऑब्जेक्ट से gets
. जैसी विधियों का उपयोग करके पढ़ सकते हैं , read
और each_line
।
मैंने आपके लिए सबसे उपयोगी विधियों के साथ एक आसान तालिका बनाई है:
विधि | विवरण |
---|---|
हो जाता है | इनपुट की एक पंक्ति पढ़ें |
पढ़ें | एक विशिष्ट मात्रा में बाइट्स पढ़ें (सभी डिफ़ॉल्ट रूप से) |
प्रत्येक_पंक्ति | एक ब्लॉक को देखते हुए, प्रत्येक पंक्ति पर पुनरावृति करें |
each_char | एक ब्लॉक को देखते हुए, प्रत्येक वर्ण पर पुनरावृति करें |
<< | डेटा जोड़ें |
रिवाइंड करें | आंतरिक स्थिति सूचक को रीसेट करें |
स्ट्रिंग | स्ट्रिंगियो ऑब्जेक्ट से एक वास्तविक स्ट्रिंग लौटाता है |
ध्यान दें कि StringIO
एक स्थिति सूचक है।
यह पॉइंटर ट्रैक करता है कि आपने कितने बाइट्स पढ़े हैं, ठीक वैसे ही जैसे कोई फ़ाइल ऑब्जेक्ट करता है।
तो हर बार जब आप gets
. जैसी किसी विधि को कॉल करते हैं या read
यह आपको उतनी मात्रा में डेटा देगा और पॉइंटर को आगे बढ़ाएगा।
यहां तक कि अनगिनत तरीके जैसे map
या each_line
पोजीशन पॉइंटर को आगे बढ़ाएगा, इसलिए इसे ध्यान में रखें।
io.each_line { |line| puts line }
आप rewind
. का उपयोग करके स्थिति सूचक को शुरुआत में रीसेट कर सकते हैं विधि:
io.pos # 45 io.rewind io.pos # 0
बुनियादी बातों के लिए बस इतना ही।
मैं आपको StringIO
. के कुछ व्यावहारिक उपयोग दिखाने जा रहा हूं , लेकिन पहले मैं आपको कुछ और दिखा दूं।
स्ट्रिंगस्कैनर के बारे में क्या?
अब आप देख चुके हैं कि StringIO
. क्या है? कर सकते हैं, लेकिन रूबी मानक पुस्तकालय में एक और स्ट्रिंग-संबंधित वर्ग शामिल है।
वह वर्ग StringScanner है।
यह भ्रमित करने वाला हो सकता है क्योंकि उनके नाम और तरीके समान हैं, लेकिन मुझे अंतर देखने में आपकी मदद करने दें।
मुख्य बात यह है :
एक StringIO
ऑब्जेक्ट दूसरे IO
को रिप्लेस कर सकता है ऑब्जेक्ट (जैसे File
या एक Socket
), लेकिन StringScanner
पार्सिंग (टोकन के एक सेट में तोड़कर कुछ पाठ की समझ बनाने) जैसी चीजों को करने के लिए है।
ये दो वर्ग अभी भी कुछ साझा करते हैं, उनके नाम में "स्ट्रिंग" होने के अलावा, वे दोनों एक आंतरिक स्थिति सूचक का उपयोग करते हैं ।
मानक इनपुट और आउटपुट को बदलना
मान लें कि आप एक कमांड-लाइन एप्लिकेशन लिख रहे हैं जो कर्नेल#गेट्स विधि का उपयोग करके उपयोगकर्ता से आउटपुट मांगता है…
...यदि आप इस कोड का परीक्षण करना चाहते हैं तो आपको हर बार हाथ से कुछ इनपुट करना होगा।
तो क्या स्वचालित परीक्षण तस्वीर से बाहर है?
नहीं, ऐसा नहीं है!
यह वह जगह है जहाँ StringIO
बचाव के लिए आता है। आप एक StringIO
को इनिशियलाइज़ कर सकते हैं अपने परीक्षण इनपुट के साथ ऑब्जेक्ट करें और फिर $stdin
. द्वारा बताए गए मानक इनपुट ऑब्जेक्ट को बदलें (यह वह जगह है जहां रूबी उपयोगकर्ता इनपुट की तलाश करती है जब आप कॉल करते हैं gets
)।
उदाहरण :
io = StringIO.new("input") $stdin = io gets # input
इस तकनीक का उपयोग puts
. जैसी विधियों से आउटपुट कैप्चर करने के लिए भी किया जा सकता है ।
प्रदर्शन विधियां डिफ़ॉल्ट आउटपुट डिवाइस पर प्रिंट होती हैं, जिसे 'मानक आउटपुट' के रूप में जाना जाता है। रूबी में इसे IO
. द्वारा दर्शाया जाता है ऑब्जेक्ट जिसे आप अपने StringIO
. से बदल सकते हैं वस्तु।
उदाहरण :
io = StringIO.new("") $stdout = io # Print to $stdout puts "Jesus Castello is from Spain & likes to help people learn Ruby." # Restore original value $stdout = STDOUT io.rewind io.read # "Jesus Castello is from Spain & likes to help people learn Ruby."
यह इनपुट संस्करण की तुलना में अधिक शामिल है, क्योंकि हम मूल STDOUT
को पुनर्स्थापित करना सुनिश्चित करना चाहते हैं ऑब्जेक्ट और हमारे StringIO
. को रिवाइंड करने के लिए ताकि हम आउटपुट पढ़ सकें।
ध्यान दें कि अधिकांश परीक्षण ढांचे में आपके लिए ऐसा करने के लिए एक विधि शामिल है (आरएसपीईसी में मिनीटेस्ट और आउटपुट मैचर के लिए Assert_output), लेकिन यह जानना हमेशा अच्छा होता है कि पर्दे के पीछे क्या हो रहा है 🙂
सारांश
आपने StringIO
. के बारे में सीखा वर्ग, जो एक वास्तविक IO
. का अनुकरण करता है वस्तु ताकि वह उस प्रकार की वस्तु के प्रतिस्थापन के रूप में कार्य कर सके।
यह उन कक्षाओं के परीक्षण के लिए उपयोगी हो सकता है जो स्क्रीन पर आउटपुट लिखते हैं या टर्मिनल के माध्यम से उपयोगकर्ता इनपुट की आवश्यकता होती है।
यदि आप StringIO
के कुछ रोचक उपयोगों के बारे में जानते हैं हमें टिप्पणियों में बताएं और इसे साझा करना न भूलें लेख ताकि अधिक से अधिक लोग इसका आनंद उठा सकें!