ハッシュをきれいに印刷する最良の方法


169

ネストされた配列とハッシュを持つ大きなハッシュがあります。簡単に印刷して、ユーザーに「読み取れる」ようにしたい。

私はto_yamlのようなものにしたいと思います-それはかなり読みやすいですが-それでもあまりにも技術的に見えます。

最終的には、これらのデータチャンクを読み取ってきれいにフォーマットする必要があるエンドユーザーになります。

助言がありますか?



オンラインユーティリティjsonviewer.stack.hu。ただし、ハッシュロケット構文では正しく機能しません。
Amit Patel

回答:


256
require 'pp'
pp my_hash

pp組み込みのソリューションが必要で、妥当な改行が必要な場合に使用します。

gemをインストールできる場合は、awesome_printを使用してください。(ユーザーによっては、index:false配列インデックスの表示をオフにするオプションを使用することもできます。)


ppはいいですが、深さを制限できないのは本当に残念です。
アキム

95

JSONがある場合JSON.pretty_generate(hash)は、awesome_printよりもシンプルで、preタグの見栄えがよく、Webページから簡単にコピーできるため、JSONをお勧めします。(参照: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オブジェクトを受け入れることに気づきました。
トニー

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)標準出力に書き込みますが、宛先を含む追加のパラメーターを取ることができることに注意してください。いいねPry::ColorPrinter.pp(obj, a_logger)
エリックアーバン

私はこれがドキュメント化されていないことに驚いています。私はいつもPryをRailsコンソールとして使用しており、他のgemを使用せずにプリティプリンターを利用する方法を長い間探していました。このソリューションが最終的に私の長い検索を終わらせたので賛成した。:-)
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 2017年

1
ほとんどの状況でまだ便利です。
エイブラム、

1
3年後のこれは信じられない!@Abramに感謝します。:)それは世界で最もエレガントなソリューションではありませんが、ピンチで物事を成し遂げます。
Nick Schwaderer、

4

ユーザーに印刷する場合は、上記の回答を使用してください。

コンソールで自分のためだけに印刷したい場合は、irbの代わりにpry gemを使用することをお勧めします。きれいな印刷以外にも、pryには他にも多くの機能があります(下記のrailscastを確認してください)。

gem install pry

そして、このrailscastをチェックしてください:

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

私が試したすべてのgemの中で、show_datagemは私にとって最も効果的でした。今では、Railsのparamsハッシュをほぼ常にログに記録するためにそれを広範囲に使用しています


0

大規模なネストされたハッシュの場合、このスクリプトが役立ちます。入れ子になったハッシュを、コピーしやすいように、インデントのみを付けたPython /ライクな構文で表示します。

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))))

(egからの応答を解析しますRestClient


0

Railsで

必要なら

  • 「きれいに印刷された」ハッシュ
  • たとえば、Rails.logger
  • 具体的にinspectは、ハッシュ内のオブジェクトで実行されます
    • これはinspect、オブジェクトのメソッドをオーバーライド/定義する場合に便利です。

...そして、これはうまくいきます!(さらに良くなると、Hashオブジェクトが大きくなり、ネストされます。)

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_inspectRailsにデフォルトで含まれているPrettyPrintからのものです。したがって、gemもJSONへの変換も必要ありません。

Railsにない

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私のプロジェクトのBig ol ' ed Hashの例と、検査したオブジェクトのプロジェクト固有のテキストを編集した例:

{<***::******************[**:****, ************************:****]********* * ****** ******************** **** :: *********** - *** ******* *********>=>
  {: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は、Google ChromeなどのWebブラウザー内で非常に読みやすいという理由だけで使用します。

それがあまりにも「技術的な」見た目が気になる場合は、ハッシュと配列の波括弧と四角括弧を空白やその他の文字に置き換える独自の関数を書く必要があると言われています。

それを行う非常に良い方法については、gsub関数を調べてください。魅力的に見えるものが見つかるまで、さまざまな文字と空白の量をいじってください。http://ruby-doc.org/core-1.9.3/String.html#method-i-gsub


7
配列とハッシュには組み込みのto_jsonメソッドがありません。これらはRailsのActiveSupportによって追加されます。
トム・デ・レイ

通常のirb / {"programming_language":{"ruby":{},"python":{}}}
pry

OPはRailsを除外しませんでした
Will Sheppard、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.