Awesome print एक अच्छा जेम है जो irb और pry में आपके आउटपुट को अधिक पठनीय बनाने के लिए फॉर्मेट करता है।
उदाहरण के लिए…
यह है कि awesome_print के साथ हैश प्रदर्शित करना कैसा दिखता है:

लेकिन यह कैसे काम करता है?
"सच्चाई केवल एक जगह मिल सकती है: कोड में।" ― रॉबर्ट सी. मार्टिन
आइए स्रोत कोड को देखकर पता लगाएं!
बहुत बढ़िया प्रिंटिंग
मुझे कोड पढ़ने के सत्र की शुरुआत प्रोजेक्ट संरचना (फाइल्स और फोल्डर्स) के त्वरित अवलोकन के साथ करना पसंद है, फिर मैं अपना अन्वेषण केंद्रित करने के लिए एक प्रश्न पूछना पसंद करता हूँ।
तो मैंने पहला प्रश्न यह सोचा:
awesome_print pry के आउटपुट को कैसे बदलता है?
अब मैं अपनी डिटेक्टिव टोपी पहनता हूँ और एक परिकल्पना बनाता हूँ:
"यह जेम $stdout को प्रतिस्थापित कर सकता है ताकि यह pry के आउटपुट को कैप्चर कर सके और फिर इसे सुंदर बना सके।"
लेकिन यह कार्यान्वयन आपको अपने आउटपुट को कस्टमाइज़ करने की अनुमति नहीं देगा, जैसे pretty_print (रूबी की मानक पुस्तकालय से) करता है।
साथ ही, हमें कोड को पार्स या यहां तक कि eval करना होगा, अच्छा विचार नहीं!
अगला:
मैंने देखा कि यह जेम कैसे लोड होता है।
यह हमें कोड में एक प्रवेश बिंदु देगा।
Awesome Print लोड करना
pry पर awesome_print लोड करने के लिए आपको यह करना होगा:
require 'awesome_print' AwesomePrint.pry!
अब हम यह ढूंढना चाहते हैं कि pry! कहाँ परिभाषित है।
मैंने Atom में "search in directory" फीचर का उपयोग करके इसे ढूंढा।
यहाँ कोड है:
def pry! Pry.print = proc { |output, value| output.puts value.ai } if defined?(Pry) end ऐसा लगता है कि Pry आपको print का मान सेट करके अपना आउटपुट संशोधित करने की अनुमति देता है।
तो यह हमारे "कहां से शुरू करें" प्रश्न का उत्तर देता है 🙂
इस "proc" चीज के बारे में अधिक जानना चाहते हैं? "The Ultimate Guide to Blocks, Procs & Lambdas" पढ़ें। यह मेरी रूबी डीप डाइव किताब का एक नमूना अध्याय है।
यह proc दो आर्गुमेंट्स लेता है:
- output
- value
और उन ऑब्जेक्ट्स पर दो मेथड्स कॉल करता है।
अगला प्रश्न:
यह 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 क्योंकि सभी ऑब्जेक्ट्स डिफ़ॉल्ट रूप से Kernel को शामिल करते हैं, उन पर यह ai मेथड उपलब्ध होगा।
अब आइए थोड़ा गहरा खोदें और देखें कि यह Inspector क्लास कैसे काम करती है।
Inspector क्लास
inspector.rb खोलते ही हमें initialize मेथड के अंदर एक विशाल ऑप्शन हैश मिलता है।
यहाँ इसका हिस्सा है:
@options = { indent: 4, # इंडेंटिंग के लिए स्पेस की संख्या। index: true, # सरणी इंडेक्स प्रदर्शित करें। html: false, # HTML के बजाय ANSI कलर कोड्स का उपयोग करें। multiline: true, # कई लाइनों में प्रदर्शित करें। # ... } उसके बाद हम यह कोड पा सकते हैं:
@formatter = AwesomePrint::Formatter.new(self) @indentator = AwesomePrint::Indentator.new(@options[:indent].abs) Thread.current[AP] ||= []
तो यह दो और ऑब्जेक्ट्स सेट करता है जो फॉर्मेटिंग और कोड के इंडेंटेशन को संभालते प्रतीत होते हैं।
लेकिन इस Thread.current चीज का क्या मतलब है?
खैर, यह आपको वर्तमान थ्रेड तक पहुंच देता है। भले ही आप अपने एप्लिकेशन में थ्रेड्स का उपयोग नहीं कर रहे हों, आपके पास एक होगा, "मुख्य" थ्रेड।
यह AP कॉन्स्टेंट सिर्फ एक कॉन्स्टेंट है जो inspector.rb के शीर्ष पर परिभाषित है:
AP = :__awesome_print__
तो यहाँ क्या हो रहा है?
Awesome print Thread.current और __awesome_print__ कुंजी का उपयोग करके कुछ डेटा सहेज रहा है जो केवल वर्तमान थ्रेड पर उपलब्ध है।
यह मल्टी-थ्रेडिंग के साथ समस्याओं से बचने के लिए उपयोग किया जाता है।
बहुत बढ़िया फॉर्मेटिंग
आइए आउटपुट फॉर्मेटिंग कोड को देखें, जो AwesomePrint::Formatter क्लास के अंदर होता है।
यह इस तरह काम करता है कि इंस्पेक्टर (ai मेथड द्वारा बनाया गया ऑब्जेक्ट) format मेथड को कॉल करेगा।
def unnested(object) @formatter.format(object, printable(object)) end
फिर Formatter क्लास पर यह format मेथड इस प्रकार के ऑब्जेक्ट से निपटने का सबसे अच्छा तरीका ढूंढेगा और थोड़े मेटाप्रोग्रामिंग का उपयोग करके दूसरा मेथड कॉल करेगा।
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 यदि आप चाहें तो अपने खुद के फॉर्मेटर्स लिख सकते हैं।
सारांश
आपने Awesome Print जेम के बारे में सीखा, जो आपको सरणियों और हैश जैसे ऑब्जेक्ट्स को एक अच्छे तरीके से प्रदर्शित करने देता है।
उम्मीद है आपको यह पसंद आया और आपने कुछ नया सीखा!
कृपया इस पोस्ट को अभी अपने पसंदीदा सोशल नेटवर्क पर शेयर करें ताकि अधिक लोग सीख सकें 🙂