Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

रूबी में डेटा और __END__ के साथ कोड और डेटा मिलाना

क्या आप जानते हैं कि रूबी आपकी स्क्रिप्ट को डेटा के स्रोत के रूप में अपनी स्रोत फ़ाइल का उपयोग करने का एक तरीका प्रदान करती है? यह एक साफ-सुथरी चाल है जो आपको एकबारगी स्क्रिप्ट और अवधारणा के प्रमाण लिखते समय कुछ समय बचा सकती है। आइए इसे देखें!

डेटा और END

नीचे दिए गए उदाहरण में, मैं __END__ . नामक एक अजीब कीवर्ड का उपयोग कर रहा हूं . नीचे सब कुछ __END__ रूबी दुभाषिया द्वारा अनदेखा कर दिया जाएगा। लेकिन अधिक दिलचस्प बात यह है कि रूबी आपको DATA . नामक एक IO ऑब्जेक्ट प्रदान करता है , जो आपको __END__ . के नीचे सब कुछ पढ़ने देता है ठीक वैसे ही जैसे आप किसी अन्य फाइल से पढ़ सकते हैं।

निम्नलिखित उदाहरण में, हम प्रत्येक पंक्ति पर पुनरावृति करते हैं और उसे प्रिंट करते हैं।

DATA.each_line do |line|
  puts line
end

__END__
Doom
Quake
Diablo

इस तकनीक का मेरा पसंदीदा व्यावहारिक उदाहरण DATA . का उपयोग करता है एक ईआरबी टेम्पलेट शामिल करने के लिए। यह वाईएएमएल, सीएसवी आदि के साथ भी काम करता है। एम

require 'erb'

time = Time.now
renderer = ERB.new(DATA.read)
puts renderer.result()

__END__
The current time is <%= time %>.

आप वास्तव में DATA . का उपयोग कर सकते हैं __END__ के ऊपर की सामग्री पढ़ने के लिए खोजशब्द। ऐसा इसलिए है क्योंकि DATA वास्तव में संपूर्ण स्रोत फ़ाइल के लिए एक सूचक है, जो __END__ . पर तेजी से अग्रेषित किया जाता है खोजशब्द। यदि आप IO ऑब्जेक्ट को प्रिंट करने से पहले रिवाइंड करते हैं तो आप इसे देख सकते हैं। नीचे दिया गया उदाहरण संपूर्ण स्रोत फ़ाइल को प्रिंट करता है।

DATA.rewind
puts DATA.read # prints the entire source file

__END__
meh

एकाधिक फ़ाइल delimma

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

नीचे दिए गए उदाहरण में, मेरे पास दो फाइलें हैं, जिनमें से प्रत्येक का अपना __END__ है खंड। हालांकि केवल एक DATA हो सकता है वैश्विक। तो __END__ दूसरी फ़ाइल का अनुभाग पहुंच योग्य नहीं है।

# first.rb
require "./second"

puts "First file\n----------------------"
puts DATA.read

print_second_data()

__END__
First end clause

# second.rb

def print_second_data
  puts "Second file\n----------------------"
  puts DATA.read # Won't output anything, since first.rb read the entire file
end

__END__

Second end clause

snhorne ~/tmp $ ruby first.rb
First file
----------------------
First end clause

Second file
----------------------

एकाधिक फ़ाइलों के लिए वैकल्पिक समाधान

सिनात्रा में एक बहुत अच्छी सुविधा है जो आपको अपने ऐप्स में एक __END__ के बाद डालकर कई इनलाइन टेम्प्लेट जोड़ने की अनुमति देती है। बयान। यह इस तरह दिखता है:

# This code is from the Sinatra docs at https://www.sinatrarb.com/intro.html
require 'sinatra'

get '/' do
  haml :index
end

__END__

@@ layout
%html
  = yield

@@ index
%div.title Hello world.

लेकिन सिनात्रा वास्तव में ऐसा कैसे कर सकती है? आखिरकार, आपका ऐप शायद रैक द्वारा लोड किया जा रहा है। आप ruby myapp.rb नहीं चलाने जा रहे हैं उत्पादन में! उन्होंने DATA . का उपयोग करने का एक तरीका निकाला होगा कई फाइलों के साथ।

हालाँकि, यदि आप सिनात्रा स्रोत में थोड़ी खुदाई करते हैं, तो आप देखेंगे कि वे एक तरह से धोखा दे रहे हैं। वे DATA . का उपयोग नहीं कर रहे हैं बिल्कुल भी। इसके बजाय वे नीचे दिए गए कोड के समान कुछ कर रहे हैं।

# I'm paraphrasing. See the original at https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1284
app, data = File.read(__FILE__).split(/^__END__$/, 2)

यह वास्तव में थोड़ा अधिक जटिल है, क्योंकि वे __FILE__ . पढ़ना नहीं चाहते हैं . वह सिर्फ sinatra/base.rb फ़ाइल होगी। इसके बजाय वे उस फ़ाइल की सामग्री प्राप्त करना चाहते हैं जिसने एक फ़ंक्शन का आह्वान किया था। वे इसे कॉलर के परिणाम को पार्स करके प्राप्त करते हैं।

कॉलर फ़ंक्शन आपको बताएगा कि वर्तमान में चल रहे फ़ंक्शन को कहां लागू किया गया था। यहां एक त्वरित उदाहरण दिया गया है:

def some_method
  puts caller
end

some_method # => caller.rb:5:in `<main>'

अब फ़ाइल नाम को वहाँ से निकालना और उस फ़ाइल के लिए DATA के समतुल्य कुछ निकालना एक बहुत ही सरल मामला है।

def get_caller_data
  puts File.read(caller.first.split(":").first).split("__END__", 2).last
end

इसका इस्तेमाल अच्छे के लिए करें, बुराई के लिए नहीं

उम्मीद है कि यह स्पष्ट है कि इस तरह की तरकीबें कुछ ऐसी नहीं हैं जिन्हें आप हर दिन इस्तेमाल करना चाहेंगे। वे बिल्कुल साफ, रखरखाव योग्य बड़े कोड आधार नहीं बनाते हैं।

हालाँकि कभी-कभी आपको एक बार की उपयोगिता स्क्रिप्ट के लिए या अवधारणा के प्रमाण के लिए कुछ त्वरित और गंदे की आवश्यकता होती है। उस स्थिति में, DATA और __END__ बहुत उपयोगी हो सकता है।


  1. लॉगर और लॉगरेज के साथ रूबी में लॉगिंग

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

  1. रूबी में फाइलें कैसे पढ़ें और लिखें (उदाहरण के साथ)

    आज आप रूबी में फाइलों को पढ़ना और लिखना सीखेंगे ताकि आप सामग्री को निकाल सकें, नई फाइलें बना सकें और अपनी जरूरत की जानकारी पा सकें! यहां बताया गया है कि हम क्या कवर करने जा रहे हैं : सामग्री 1 रूबी में फ़ाइलें कैसे पढ़ें 2 रूबी में फ़ाइल को कैसे लिखें 3 रूबी फ़ाइल विधियाँ 4 निर्देशिका संचालन 5

  1. फ़ाइल इतिहास के साथ Windows 10 में डेटा कैसे बचाएं और पुनर्स्थापित करें

    हम समझते हैं कि हमारी महत्वपूर्ण फाइलों और दस्तावेजों को अनपेक्षित स्थितियों जैसे हार्ड ड्राइव विफलता, पावर आउटेज या कुछ अन्य मुद्दों से बचाना कितना महत्वपूर्ण है। अधिमानतः, हमें नियमित रूप से अपने डेटा का बैकअप लेना चाहिए। हालाँकि, जब विंडोज ओएस के बारे में बात की जाती है, तो आप नियमित आधार पर सभी