멋진 인쇄는 출력 형식을 irb
로 지정하는 멋진 보석입니다. &pry
가독성을 높일 수 있습니다.
예를 들어...
이것은 awesome_print
로 해시를 표시하는 것입니다. 다음과 같이 보입니다:
하지만 어떻게 작동합니까?
<블록 인용>"진실은 오직 한 곳, 즉 코드에서만 찾을 수 있습니다." ― 로버트 C. 마틴
소스 코드를 살펴보고 알아봅시다!
멋진 인쇄
저는 프로젝트 구조(파일 및 폴더)에 대한 간략한 개요와 함께 코드 읽기 세션을 시작한 다음 앞으로의 탐색에 집중할 수 있는 질문을 하고 싶습니다.
그래서 제가 생각해낸 첫 번째 질문은 :
awesome_print
는 어떻게 pry의 출력을 변경하시겠습니까?
이제 탐정 모자를 쓰고 가설을 세웁니다. :
"이 보석은 $stdout
을 대체할 수 있습니다. pry의 출력을 캡처한 다음 예쁘게 만들 수 있도록."
그러나 이 구현에서는 pretty_print
와 같은 출력을 사용자 정의할 수 없습니다. (Ruby의 표준 라이브러리에서) 그렇습니다.
또한 코드를 구문 분석하거나 평가해야 할 수도 있습니다. 좋은 생각은 아닙니다!
다음 :
이 보석이 어떻게 로드되는지 살펴보았습니다.
이것은 우리에게 코드에 대한 진입점을 제공할 것입니다.
멋진 인쇄물 로드 중
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}" 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
메서드)는 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
상수는 핵심 Ruby 클래스 및 :self
를 나타내는 기호 배열입니다. "찾을 수 없음"을 의미하는 데 사용되는 기호입니다(이 예에서는 일반적으로 Ruby가 아님).
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 gem에 대해 배웠습니다.
이 시간을 즐기고 새로운 것을 배웠기를 바랍니다!
더 많은 사람들이 배울 수 있도록 지금 이 게시물을 즐겨찾는 소셜 네트워크에 공유하세요 🙂