การพิมพ์ที่ยอดเยี่ยมเป็นอัญมณีที่ดีที่จัดรูปแบบผลลัพธ์ของคุณใน irb
&แงะ
เพื่อให้อ่านง่ายขึ้น
ตัวอย่างเช่น…
นี่คือสิ่งที่แสดงแฮชด้วย awesome_print
ดูเหมือนว่า:
แต่วิธีนี้ทำงานอย่างไร
“ความจริงสามารถพบได้ในที่เดียวเท่านั้น:รหัส” ― โรเบิร์ต ซี. มาร์ติน
มาดูซอร์สโค้ดกันเพื่อหาคำตอบกัน!
การพิมพ์ที่ยอดเยี่ยม
ฉันชอบเริ่มเซสชันการอ่านโค้ดพร้อมภาพรวมคร่าวๆ ของโครงสร้างโปรเจ็กต์ (ไฟล์และโฟลเดอร์) จากนั้นฉันก็ชอบถามคำถามเพื่อเน้นการสำรวจของฉันต่อไป
คำถามแรกที่ฉันคิดคือ :
awesome_print
. เป็นอย่างไร เปลี่ยนผลลัพธ์ของ pry?
ตอนนี้ฉันสวมหมวกนักสืบและตั้งสมมติฐาน :
“อัญมณีนี้สามารถแทนที่ $stdout
เพื่อให้สามารถดักจับผลลัพธ์ของ pry แล้วทำให้มันสวยได้”
แต่การใช้งานนี้จะไม่อนุญาตให้คุณปรับแต่งผลลัพธ์ของคุณ เช่น pretty_print
(จาก Ruby's Standard Library) ทำได้
นอกจากนี้ เราจะต้องแยกวิเคราะห์ หรือแม้แต่โค้ด eval ก็ยังไม่ใช่ความคิดที่ดี!
ถัดไป :
ฉันดูวิธีการโหลดอัญมณีนี้
ซึ่งจะทำให้เราเข้าสู่โค้ดได้
กำลังโหลดงานพิมพ์ที่ยอดเยี่ยม
ในการโหลด awesome_print
ในการแงะ คุณต้องทำสิ่งนี้:
require 'awesome_print' AwesomePrint.pry!
ตอนนี้เราต้องการค้นหาว่า pry!
ถูกกำหนดไว้แล้ว
ฉันใช้คุณลักษณะ "ค้นหาในไดเรกทอรี" ใน Atom เพื่อค้นหา
นี่คือรหัส :
def pry! Pry.print = proc { |output, value| output.puts value.ai } if defined?(Pry) end
ดูเหมือนว่า Pry จะให้คุณแก้ไขผลลัพธ์ได้โดยการตั้งค่า print
.
นี่จึงเป็นคำตอบสำหรับคำถามว่า "จะเริ่มต้นอย่างไร" 🙂
ต้องการเรียนรู้เพิ่มเติมเกี่ยวกับสิ่งนี้ "proc" หรือไม่? อ่าน “คู่มือขั้นสูงสำหรับบล็อก โปรคส์ และแลมบ์ดาส” นี่คือตัวอย่างบทจากหนังสือ Ruby Deep Dive ของฉัน
โปรนี้รับสองอาร์กิวเมนต์ :
- เอาต์พุต
- ค่า
และเรียกใช้สองวิธีบนวัตถุเหล่านั้น
คำถามถัดไป :
นี่คืออะไร 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}" เจ๋ง =น่ากลัว.html_safe ถ้ากำหนดไว้? ActiveSupport สิ้นสุด Awesomeendalias :awesome_inspect :ai
เนื่องจากวัตถุทั้งหมดมี เคอร์เนล
โดยค่าเริ่มต้น พวกเขาจะมี ai
. นี้ วิธีการที่มีอยู่
มาเจาะลึกลงไปอีกหน่อยแล้วมาดูกันว่า สารวัตร
งานของชั้นเรียน
กลุ่มสารวัตร
ทันทีหลังจากเปิด 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
นี้ AP
ค่าคงที่เป็นเพียงค่าคงที่ซึ่งกำหนดไว้ที่ด้านบนของ inspector.rb
:
AP = :__awesome_print__
เกิดอะไรขึ้นที่นี่?
งานพิมพ์ที่ยอดเยี่ยมกำลังใช้ Thread.current
&__awesome_print__
คีย์เพื่อบันทึกข้อมูลบางอย่างที่มีอยู่ในเธรดปัจจุบันเท่านั้น
ใช้เพื่อหลีกเลี่ยงปัญหาเกี่ยวกับมัลติเธรด
การจัดรูปแบบที่ยอดเยี่ยม
มาดูโค้ดการจัดรูปแบบเอาต์พุตซึ่งเกิดขึ้นใน AwesomePrint::Formatter
ชั้นเรียน
วิธีการทำงานคือผู้ตรวจสอบ (วัตถุที่สร้างโดย ai
วิธี) จะเรียก รูปแบบ
วิธีการ
def unnested(object) @formatter.format(object, printable(object)) end
แล้ว รูปแบบ
. นี้ วิธีการใน ฟอร์แมตเตอร์
class จะหาวิธีที่ดีที่สุดในการจัดการกับวัตถุประเภทนี้ &เรียกวิธีอื่นโดยใช้ metaprogramming เล็กน้อย
นี่คือวิธีการ :
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
เพื่อให้เข้าใจ ฟอร์แมตเตอร์
.นี้ คลาสเรายังต้องดูที่ cast
วิธีการ:
def cast(object, type) CORE.grep(type)[0] || :self end
CORE
ค่าคงที่คืออาร์เรย์ของสัญลักษณ์แทนคลาส Ruby หลัก &:self
เป็นสัญลักษณ์ที่ใช้แปลว่า "ไม่พบ" (ในตัวอย่างนี้ ไม่ได้ใช้ในภาษา Ruby โดยทั่วไป)
CORE = [:array, :bigdecimal, :class, :dir, :file, :hash, :method, :rational, :set, :struct, :unboundmethod]
อะไรจะเกิดขึ้น :
หากวัตถุที่กำลังจัดรูปแบบอยู่ในรายการ "คลาสหลัก" วัตถุนั้นจะได้รับรูปแบบเฉพาะ
มิเช่นนั้นจะเป็นแบบทั่วไป
ตัวจัดรูปแบบเฉพาะถูกกำหนดภายใต้ lib/awesome_print/formatters/
ไดเรกทอรี &รวมสิ่งต่าง ๆ เช่น Array
, แฮช
&คลาส
.
ตัวอย่างเช่น นี่คือวิธีการจัดรูปแบบสำหรับคลาส:
def format superclass = klass.superclass if superclass colorize("#{klass.inspect} < #{superclass}", :class) else colorize(klass.inspect, :class) end end
คุณสามารถเขียนตัวจัดรูปแบบของคุณเองได้หากต้องการ
สรุป
คุณได้เรียนรู้เกี่ยวกับ Awesome Print gem ซึ่งช่วยให้คุณแสดงอ็อบเจ็กต์ เช่น อาร์เรย์และแฮชได้อย่างดี
หวังว่าคุณจะสนุกกับสิ่งนี้และเรียนรู้สิ่งใหม่!
โปรดแชร์โพสต์นี้บนโซเชียลเน็ตเวิร์กที่คุณชื่นชอบตอนนี้ เพื่อให้ผู้คนได้เรียนรู้มากขึ้น 🙂