विस्मयकारी प्रिंट एक अच्छा रत्न है जो आपके आउटपुट को irb
. में प्रारूपित करता है &pry
इसे और अधिक पठनीय बनाने के लिए।
उदाहरण के लिए…
यह वही है जो awesome_print
के साथ हैश प्रदर्शित करता है ऐसा दिखता है:
लेकिन यह कैसे काम करता है?
<ब्लॉककोट>"सत्य केवल एक ही स्थान पर पाया जा सकता है:कोड।" ― रॉबर्ट सी. मार्टिन
आइए इसका पता लगाने के लिए स्रोत कोड पर एक नज़र डालें!
अद्भुत रूप से प्रिंट करना
मैं प्रोजेक्ट संरचना (फ़ाइलें और फ़ोल्डर) के त्वरित अवलोकन के साथ एक कोड रीडिंग सत्र शुरू करना चाहता हूं, फिर मैं अपने अन्वेषण को आगे बढ़ाने के लिए एक प्रश्न पूछना चाहता हूं।
तो पहला प्रश्न जो मैं लेकर आया हूं वह है :
awesome_print
कैसे करता है pry का आउटपुट बदलें?
अब मैं अपनी जासूसी टोपी लगाता हूं और एक परिकल्पना करता हूं :
“यह रत्न $stdout
की जगह ले सकता है ताकि यह pry के आउटपुट को कैप्चर कर सके और फिर इसे सुंदर बना सके।"
लेकिन यह कार्यान्वयन आपको अपने आउटपुट को अनुकूलित करने की अनुमति नहीं देगा, जैसे pretty_print
(रूबी के मानक पुस्तकालय से) करता है।
साथ ही, हमें पार्स करना होगा, या कोड को भी निकालना होगा, यह एक अच्छा विचार नहीं है!
अगला :
मैंने देखा कि यह रत्न कैसे लोड होता है।
यह हमें कोड में एक प्रवेश बिंदु देगा।
बहुत बढ़िया प्रिंट लोड हो रहा है
awesome_print
लोड करने के लिए आपको यह करना होगा:
require 'awesome_print' AwesomePrint.pry!
अब हम यह जानना चाहते हैं कि pry!
. कहां है परिभाषित किया गया है।
मैंने इसे खोजने के लिए एटम में "निर्देशिका में खोजें" सुविधा का उपयोग किया।
यह रहा कोड :
def pry! Pry.print = proc { |output, value| output.puts value.ai } if defined?(Pry) end
ऐसा लगता है कि Pry आपको print
. का मान सेट करके इसके आउटपुट को संशोधित करने की अनुमति देता है ।
तो यह हमारे "कहां से शुरू करें" प्रश्न का उत्तर देता है
<ब्लॉककोट>इस "खरीद" चीज़ के बारे में और जानना चाहते हैं? "ब्लॉक, प्रोसेस और लैम्ब्डा के लिए अंतिम गाइड" पढ़ें। यह मेरी रूबी डीप डाइव पुस्तक का एक नमूना अध्याय है।
इस प्रक्रिया में दो तर्क लगते हैं :
- आउटपुट
- मान
और यह उन वस्तुओं पर दो विधियों को कॉल करता है।
अगला प्रश्न :
यह क्या है ai
विधि?
यह Kernel
. पर परिभाषित एक विधि है मॉड्यूल:
def ai(options = {}) ap = AwesomePrint::Inspector.new(options) awesome = ap.awesome(self) if options[:html] awesome = "</pre>#{awesome}</pre>" awesome = awesome.html_safe if defined? ActiveSupport end awesome end alias :awesome_inspect :ai#{awesome}" Awesome =Awesome.html_safe अगर परिभाषित किया गया हो? ActiveSupport अंत Awesomeendalias :awesome_inspect :ai
क्योंकि सभी वस्तुओं में Kernel
. शामिल होता है डिफ़ॉल्ट रूप से, उनके पास यह ai
होगा उन पर उपलब्ध विधि।
आइए अब थोड़ा और गहराई से देखें और देखें कि यह कैसे Inspector
क्लास वर्क्स।
निरीक्षक वर्ग
inspector.rb
खोलने के तुरंत बाद हमें initialize
. के अंदर एक विशाल विकल्प हैश मिलता है विधि।
यहां इसका एक अंश दिया गया है :
@options = { indent: 4, # Number of spaces for indenting. index: true, # Display array indices. html: false, # Use ANSI color codes rather than HTML. multiline: true, # Display in multiple lines. # ... }
उसके बाद हमें यह कोड मिल सकता है :
@formatter = AwesomePrint::Formatter.new(self) @indentator = AwesomePrint::Indentator.new(@options[:indent].abs) Thread.current[AP] ||= []
तो यह दो और ऑब्जेक्ट सेट करता है जो कोड के फ़ॉर्मेटिंग और इंडेंटेशन को संभालने लगते हैं।
लेकिन इसमें क्या है Thread.current
बात?
खैर, यह आपको वर्तमान धागे तक पहुंच प्रदान करता है। यहां तक कि अगर आप अपने आवेदन में धागे का उपयोग नहीं कर रहे हैं तो आपके पास एक "मुख्य" धागा होगा।
यह AP
स्थिरांक केवल एक स्थिरांक है जिसे inspector.rb
. के शीर्ष पर परिभाषित किया गया है :
AP = :__awesome_print__
तो यहाँ क्या हो रहा है?
बढ़िया प्रिंट Thread.current
का उपयोग कर रहा है और __awesome_print__
कुछ डेटा को सहेजने की कुंजी जो केवल वर्तमान थ्रेड पर उपलब्ध है।
इसका उपयोग मल्टी-थ्रेडिंग की समस्याओं से बचने के लिए किया जाता है।
अद्भुत स्वरूपण
आइए आउटपुट स्वरूपण कोड पर एक नज़र डालें, जो AwesomePrint::Formatter
के अंदर होता है कक्षा।
इसके काम करने का तरीका यह है कि इंस्पेक्टर (ai
. द्वारा बनाई गई वस्तु) method) format
. को कॉल करेगा विधि।
def unnested(object) @formatter.format(object, printable(object)) end
फिर यह format
Formatter
. पर विधि क्लास इस प्रकार के ऑब्जेक्ट से निपटने का सबसे अच्छा तरीका ढूंढेगा और कुछ मेटाप्रोग्रामिंग का उपयोग करके दूसरी विधि को कॉल करेगा।
यह रहा तरीका :
def format(object, type = nil) core_class = cast(object, type) awesome = if core_class != :self send(:"awesome_#{core_class}", object) # Core formatters. else awesome_self(object, type) # Catch all that falls back to object.inspect. end awesome end
इसे समझने के लिए Formatter
कक्षा में हमें cast
. पर भी एक नज़र डालने की आवश्यकता है विधि:
def cast(object, type) CORE.grep(type)[0] || :self end
CORE
स्थिरांक कोर रूबी कक्षाओं का प्रतिनिधित्व करने वाले प्रतीकों की एक सरणी है और :self
एक प्रतीक है जिसका अर्थ है "नहीं मिला" (सिर्फ इस उदाहरण में, सामान्य रूप से रूबी में नहीं)।
CORE = [:array, :bigdecimal, :class, :dir, :file, :hash, :method, :rational, :set, :struct, :unboundmethod]
यह क्या होता है :
यदि स्वरूपित की जा रही वस्तु "कोर क्लास" सूची में है तो उसे एक विशेष प्रारूप मिलेगा।
अन्यथा, इसे एक सामान्य मिल जाएगा।
स्पेशलाइज्ड फॉर्मेटर्स को lib/awesome_print/formatters/
. के तहत परिभाषित किया गया है निर्देशिका और Array
. जैसी चीज़ें शामिल करें , Hash
&Class
।
उदाहरण के लिए, यहां कक्षाओं के लिए फ़ॉर्मेटर विधि है:
def format superclass = klass.superclass if superclass colorize("#{klass.inspect} < #{superclass}", :class) else colorize(klass.inspect, :class) end end
आप चाहें तो अपने खुद के फॉर्मेटर लिख सकते हैं।
सारांश
आपने विस्मयकारी प्रिंट रत्न के बारे में सीखा है, जो आपको सरणियों और हैश जैसी वस्तुओं को अच्छे तरीके से प्रदर्शित करने देता है।
आशा है कि आपने इसका आनंद लिया और कुछ नया सीखा!
कृपया इस पोस्ट को अपने पसंदीदा सोशल नेटवर्क पर अभी शेयर करें ताकि और लोग सीख सकें 🙂