해시를 예쁘게 인쇄하는 가장 좋은 방법


169

중첩 배열과 해시가있는 큰 해시가 있습니다. 간단히 인쇄하여 사용자가 읽을 수 있도록하고 싶습니다.

나는 to_yaml과 같은 것이기를 원합니다-꽤 읽을 수 있지만 여전히 너무 기술적으로 보입니다.

궁극적으로 이러한 데이터 청크를 읽어야하는 최종 사용자가되므로 형식을 명확하게 지정해야합니다.

어떤 제안?



온라인 유틸리티 jsonviewer.stack.hu . 그러나 해시 로켓 구문에서는 제대로 작동하지 않습니다.
Patel Amit

답변:


256
require 'pp'
pp my_hash

pp내장 솔루션이 필요하고 합리적인 줄 바꿈을 원할 경우 사용하십시오 .

gem을 설치할 수 있으면 awesome_print를 사용하십시오 . (사용자에 따라 index:false옵션을 사용하여 배열 인덱스 표시를 해제 할 수 있습니다 .)


pp는 좋지만 실제로 깊이를 제한 할 수없는 것은 유감입니다.
akim

95

JSON이있는 JSON.pretty_generate(hash)경우 awesome_print 보다 간단 하고 pre태그 가 멋지게 보이고 웹 페이지에서 쉽게 복사 할 수 있기 때문에 권장 합니다. (또한 Ruby on Rails에서 JSON 출력을 "예쁜"형식으로 지정하려면 어떻게해야합니까? )


이 답변은 실제 예에서 도움이 될 것입니다
Travis Bear

@TravisBear 내 답변에서 "참조"링크를 클릭하면 예제 출력이 있습니다. 나는 특히이 답변을 추천한다 : stackoverflow.com/a/1823885/109618
David J.

8
그것은 것puts JSON.pretty_generate(hash)
joeloui

JSON을 작성해야하는 경우 Ruby 또는 JS에서 예쁜 JSON을 작성하기 위해 내 라이브러리 (무료, OSS, 광고 없음)를 추천 해주세요 . NeatJSON (Ruby)NeatJSON (Online / JS)
Phrogz

죄송합니다. pretty_generate는 json 텍스트가 아닌 Ruby 객체를 허용합니다.
Tony

26

보다 나를 더 잘 작동 또 다른 해결책 pp이나 awesome_print:

require 'pry' # must install the gem... but you ALWAYS want pry installed anyways
Pry::ColorPrinter.pp(obj)

2
참고 Pry::ColorPrinter.pp(obj)표준 출력에 쓰기를하지만, 대상 등의 추가 PARAMS를 취할 수 있습니다. 처럼Pry::ColorPrinter.pp(obj, a_logger)
에릭 Urban

나는 이것이 더 잘 문서화되지 않았다는 것에 놀랐다. 나는 항상 pry를 Rails 콘솔로 사용하고 있으며 다른 보석을 사용하지 않고 예쁜 프린터를 사용하는 방법을 오랫동안 찾고있다. 이 솔루션이 마침내 긴 검색을 끝내기 때문에 상향 조정되었습니다. :-)
wiz

20

멋진 gem 작업은 없지만 JSON이있는 경우이 CLI 행은 해시에서 작동합니다.

puts JSON.pretty_generate(my_hash).gsub(":", " =>")

#=>
{
  :key1 => "value1",

  :key2 => "value2",

  :key3 => "value3"
}

8
":"를 포함하는 모든 키와 값을 엉망으로 만들기 때문에 하향 투표
thomax

1
이것은 또한 null (JSON) 대 nil (Ruby)을 처리하지 않습니다.
Rennex

1
대부분의 상황에서 여전히 편리합니다.
Abram

1
이 3 년 후 믿을 수 없다! 감사합니다 @Abram. :) 그것은 세상에서 가장 우아한 솔루션은 아니지만 일을 아주 쉽게 처리합니다.
Nick Schwaderer

4

사용자에게 인쇄하는 경우 위의 답변을 사용하십시오.

콘솔에서 직접 인쇄하려면 irb 대신 pry gem을 사용하는 것이 좋습니다. 예쁜 인쇄 외에도 pry는 다른 많은 기능을 가지고 있습니다 (아래의 레일 캐스트 확인)

보석 설치

이 레일 캐스트를 확인하십시오.

http://railscasts.com/episodes/280-pry-with-rails


3

제 키가 제정신임을 믿는 경우 json으로 쉽게 할 수 있습니다.

JSON.pretty_generate(a: 1, 2 => 3, 3 => nil).
  gsub(": null", ": nil").
  gsub(/(^\s*)"([a-zA-Z][a-zA-Z\d_]*)":/, "\\1\\2:"). # "foo": 1 -> foo: 1
  gsub(/(^\s*)(".*?"):/, "\\1\\2 =>") # "123": 1 -> "123" => 1

{
  a: 1,
  "2" => 3,
  "3" => nil
}

1

Pry를 사용하면 ~ / .pryrc에 다음 코드를 추가하면됩니다.

require "awesome_print"
AwesomePrint.pry!

1

내가 시도한 모든 보석 중 보석 show_data이 나를 위해 가장 잘 작동했습니다. 이제 광범위하게 paras 해시를 거의 항상 Rails에 기록하는 데 사용합니다.


0

큰 중첩 해시의 경우이 스크립트가 도움이 될 수 있습니다. 그것은 쉽게 복사 할 수 있도록 들여 쓰기만으로 멋진 파이썬과 같은 구문으로 중첩 해시를 인쇄합니다.

module PrettyHash
  # Usage: PrettyHash.call(nested_hash)
  # Prints the nested hash in the easy to look on format
  # Returns the amount of all values in the nested hash

  def self.call(hash, level: 0, indent: 2)
    unique_values_count = 0
    hash.each do |k, v|
      (level * indent).times { print ' ' }
      print "#{k}:"
      if v.is_a?(Hash)
        puts
        unique_values_count += call(v, level: level + 1, indent: indent)
      else
        puts " #{v}"
        unique_values_count += 1
      end
    end
    unique_values_count
  end
end

사용법 예 :

  h = {a: { b: { c: :d }, e: :f }, g: :i }
  PrettyHash.call(h)

a:
  b:
    c: d
  e: f
g: i
=> 3

반환 된 값은 중첩 해시의 모든 최종 수준 값의 개수 (3)입니다.


0

json과 rouge를 사용하는 또 다른 접근법이 있습니다.

require 'json'
require 'rouge'

formatter = Rouge::Formatters::Terminal256.new
json_lexer = Rouge::Lexers::JSON.new

puts formatter.format(json_lexer.lex(JSON.pretty_generate(JSON.parse(response))))

(예를 들어 응답을 파싱 RestClient)


0

레일에서

필요한 경우

  • "꽤 인쇄 된"해시
  • 예를 들어 Rails.logger
  • 특히 inspect해시의 객체에서 실행 됩니다.
    • 이는 재정의 / 정의 할 때 유용합니다. inspect객체 메소드

... 그러면 잘 작동합니다! (그리고 더 좋을수록 해시 객체가 더 크고 중첩됩니다.)

logger.error my_hash.pretty_inspect

예를 들면 다음과 같습니다.

class MyObject1
  def inspect
    "<#{'*' * 10} My Object 1 #{'*' * 10}>"
  end
end

class MyObject2
  def inspect
    "<#{'*' * 10} My Object 2 #{'*' * 10}>"
  end
end

my_hash = { a: 1, b: MyObject1.new, MyObject2.new => 3 }

Rails.logger.error my_hash
# {:a=>1, :b=><********** My Object 1 **********>, <********** My Object 2 **********>=>3}

# EW! ^

Rails.logger.error my_hash.pretty_inspect
# {:a=>1,
#  :b=><********** My Object 1 **********>,
#  <********** My Object 2 **********>=>3}

pretty_inspect PrettyPrint에서 온레일에는 기본적으로 포함되는 . 따라서 gem이 필요없고 JSON으로의 변환이 필요하지 않습니다.

레일에 없음

Rails에 없거나 위와 같은 이유로 위의 방법이 실패하면 require "pp"먼저 사용하십시오 . 예를 들면 다음과 같습니다.

require "pp"  # <-----------

class MyObject1
  def inspect
    "<#{'*' * 10} My Object 1 #{'*' * 10}>"
  end
end

class MyObject2
  def inspect
    "<#{'*' * 10} My Object 2 #{'*' * 10}>"
  end
end

my_hash = { a: 1, b: MyObject1.new, MyObject2.new => 3 }

puts my_hash
# {:a=>1, :b=><********** My Object 1 **********>, <********** My Object 2 **********>=>3}

# EW! ^

puts my_hash.pretty_inspect
# {:a=>1,
#  :b=><********** My Object 1 **********>,
#  <********** My Object 2 **********>=>3}

전체 예

pretty_inspect검사 된 객체의 프로젝트 특정 텍스트가있는 프로젝트의 큰 해시 예 :

{<***::******************[**:****, ************************:****]********* * ****** ******************** **** :: *********** - *** ******* *********>=>
  {:errors=>
    ["************ ************ ********** ***** ****** ******** ***** ****** ******** **** ********** **** ***** ***** ******* ******",
     "************ ************ ********** ***** ****** ******** ***** ****** ******** **** ********** is invalid",
     "************ ************ ********** ***** ****** ******** is invalid",
     "************ ************ ********** is invalid",
     "************ ************ is invalid",
     "************ is invalid"],
   :************=>
    [{<***::**********[**:****, *************:**, ******************:*, ***********************:****] :: **** **** ****>=>
       {:************=>
         [{<***::***********[**:*****, *************:****, *******************:**]******* :: *** - ******* ***** - *>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: *** - *>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ********* - *>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ********** - ********** *>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ******** - *>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: **** - *******>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: *** - ********** ***** - *>=>
            {}}]}},
     {<***::**********[**:****, *************:**, ******************:*, ***********************:****] ******************** :: *** - *****>=>
       {:errors=>
         ["************ ********** ***** ****** ******** ***** ****** ******** **** ********** **** ***** ***** ******* ******",
          "************ ********** ***** ****** ******** ***** ****** ******** **** ********** is invalid",
          "************ ********** ***** ****** ******** is invalid",
          "************ ********** is invalid",
          "************ is invalid"],
        :************=>
         [{<***::***********[**:*****, *************:****, *******************:***]******* :: ****** - ** - ********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:***]******* :: ****** - ** - ********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ****** - ** - *******>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]*********** :: ****>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ****** - ** - *******>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ****** - ** - *********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ****** - ** - *******>=>
            {:errors=>
              ["********** ***** ****** ******** ***** ****** ******** **** ********** **** ***** ***** ******* ******",
               "********** ***** ****** ******** ***** ****** ******** **** ********** is invalid",
               "********** ***** ****** ******** is invalid",
               "********** is invalid"],
             :**********************=>
              [{<***::*******************[**:******, ************************:***]****-************ ******************** ***: * :: *** - ***** * ****** ** - ******* * **: *******>=>
                 {:errors=>
                   ["***** ****** ******** **** ********** **** ***** ***** ******* ******",
                    "***** ****** ******** **** ********** is invalid"],
                  :***************=>
                   [{<***::********************************[**:******, *************:******, ***********:******, ***********:"************ ************"]** * *** * ****-******* * ******** * ********* ******************** *********************: ***** :: "**** *" -> "">=>
                      {:errors=>["**** ***** ***** ******* ******"],
                       :**********=>
                        {<***::*****************[**:******, ****************:["****** ***", "****** ***", "****** ****", "******* ***", "******* ****", "******* ***", "****"], **:""] :: "**** *" -> "">=>
                          {:errors=>
                            ["***** ******* ******",
                             "***** ******* ******"]}}}}]}}]}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ****** - ** - *********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ****** - ** - *********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:***]******* :: ****** - ** - ********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:***]******* :: ****** - ** - **********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:***]******* :: ****** - ** - **********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:***]******* :: ****** - ** - **********>=>
            {}}]}}]}}

-4

Rails에서 Ruby의 배열과 해시는 내장 된 to_json 함수를 가지고 있습니다. JSON과 같은 웹 브라우저 (예 : Chrome)에서 읽을 수 있기 때문에 JSON을 사용합니다.

너무 "기술적으로 보이는"것에 대해 걱정한다면 해시와 배열의 중괄호와 대괄호를 공백과 다른 문자로 대체하는 함수를 작성해야 할 것입니다.

아주 좋은 방법으로 gsub 함수를 찾으십시오. 당신이 매력적인 것처럼 보일 때까지 다른 캐릭터와 다른 양의 공백으로 계속 놀아보십시오. http://ruby-doc.org/core-1.9.3/String.html#method-i-gsub


7
배열과 해시는 내장 된 to_json 메소드를 가지고 있지 않습니다. 이들은 Rails의 ActiveSupport에 의해 추가됩니다.
Tom De Leu

그것은 정상 IRB / 놀리려는보다 더 나쁜 :{"programming_language":{"ruby":{},"python":{}}}
Darek Nędza

OP는 Rails를 배제하지 않았다
Will Sheppard
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.