awesome_print gem format output ใน irb/pry ให้อ่านง่าย สีสัน สวยงาม
Printing Awesomely
อ่าน source code หาว่าทำงานยังไง เริ่มจาก project structure แล้วถามคำถาม: "awesome_print เปลี่ยน output ของ pry อย่างไร?"
Loading Awesome Print
require 'awesome_print' AwesomePrint.pry!
หา pry! method:
def pry!
Pry.print = proc { |output, value| output.puts value.ai } if defined?(Pry)
end
Pry ให้ override print ผ่าน Pry.print proc รับ output, value เรียก value.ai
The ai Method
Defined on Kernel module (ทุกอ็อบเจ็กต์มี):
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
The Inspector Class
Inspector.new setup options (indent, index, html, multiline, colors...) สร้าง Formatter และ Indentator ใช้ Thread.current[:__awesome_print__] เก็บข้อมูล per-thread (thread safety)
Awesome Formatting
Formatter.format หา formatter ที่เหมาะสม:
def format(object, type = nil)
core_class = cast(object, type)
awesome = if core_class != :self
send(:"awesome_#{core_class}", object) # specialized formatters
else
awesome_self(object, type) # fallback to inspect
end
awesome
end
def cast(object, type)
CORE.grep(type)[0] || :self
end
CORE = [:array, :bigdecimal, :class, :dir, :file, :hash, :method, :rational, :set, :struct, :unboundmethod]
Core classes ได้ specialized formatter (ใน lib/awesome_print/formatters/) ไม่ใช่ fallback เป็น generic ตัวอย่าง formatter สำหรับ Class:
def awesome_class(klass)
superclass = klass.superclass
if superclass
colorize("#{klass.inspect} < #{superclass}", :class)
else
colorize(klass.inspect, :class)
end
end
เขียน custom formatters ได้
Summary
Awesome Print gem แสดงอ็อบเจ็กต์ (arrays, hashes) สวยง่าย เรียนรู้โครงสร้าง: Inspector, Formatter, core class formatters, thread-local storage