Najlepszy sposób na ładne wydrukowanie skrótu

169

Mam duży skrót z zagnieżdżonymi tablicami i skrótami. Chciałbym go po prostu wydrukować, aby był „czytelny” dla użytkownika.

Chciałbym, żeby to było coś w rodzaju to_yaml - to całkiem czytelne - ale wciąż zbyt techniczne.

Ostatecznie będą to użytkownicy końcowi, którzy będą musieli czytać te fragmenty danych, więc muszą zostać sformatowane w sposób czysty.

Jakieś sugestie?

Adam O'Connor
źródło
narzędzie online jsonviewer.stack.hu . Jednak nie działa poprawnie dla składni rakiety mieszającej.
Amit Patel

Odpowiedzi:

256
require 'pp'
pp my_hash

Użyj, ppjeśli potrzebujesz wbudowanego rozwiązania i chcesz po prostu rozsądnych podziałów linii.

Użyj awesome_print, jeśli możesz zainstalować klejnot. (W zależności od użytkowników możesz chcieć skorzystać z index:falseopcji wyłączenia wyświetlania indeksów tablic).

Phrogz
źródło
pp jest fajne, ale szkoda, że ​​nie można ograniczyć głębokości.
akim
95

Jeśli masz JSON, polecam, JSON.pretty_generate(hash)ponieważ jest prostszy niż awesome_print , świetnie wygląda w pretagu i pozwala na łatwe kopiowanie ze strony internetowej. (Zobacz także: Jak „ładnie” sformatować wyjście JSON w Ruby on Rails? )

David J.
źródło
Ta odpowiedź przydałaby się na rzeczywistym przykładzie
Travis Bear
@TravisBear Jest przykładowe wyjście, jeśli klikniesz link „zobacz także” w mojej odpowiedzi. W szczególności polecam tę odpowiedź: stackoverflow.com/a/1823885/109618
David J.
8
To byłobyputs JSON.pretty_generate(hash)
joeloui
Jeśli potrzebujesz utworzyć JSON, pozwól mi polecić moją własną (bezpłatną, OSS, bez reklam) bibliotekę do tworzenia ładnego JSON z Ruby lub JS: NeatJSON (Ruby) i NeatJSON (Online / JS)
Phrogz
Przepraszam, teraz zdaję sobie sprawę, że pretty_generate akceptuje obiekt Ruby, a nie tekst json.
Tony
26

Kolejne rozwiązanie, które u mnie działa lepiej niż pplub awesome_print:

require 'pry' # must install the gem... but you ALWAYS want pry installed anyways
Pry::ColorPrinter.pp(obj)
Alex D.
źródło
2
Zauważ, że Pry::ColorPrinter.pp(obj)zapisuje do standardu, ale może przyjmować dodatkowe parametry, w tym miejsce docelowe. Na przykładPry::ColorPrinter.pp(obj, a_logger)
Eric Urban
Dziwię się, że nie jest to lepiej udokumentowane: zawsze używam pry jako mojej konsoli Rails i od dawna szukałem, jak podłączyć się do jej ładnej drukarki bez użycia kolejnego klejnotu. Głosowałem za, ponieważ to rozwiązanie ostatecznie zakończyło moje długie poszukiwania. :-)
wiz
20

Jeśli nie masz żadnej fantazyjnej akcji klejnotu, ale masz JSON, ta linia CLI będzie działać na hashu:

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

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

  :key2 => "value2",

  :key3 => "value3"
}
Nick Schwaderer
źródło
8
Głosowanie negatywne, ponieważ spowoduje to zepsucie wszystkich kluczy i wartości zawierających „:”
thomax
1
Nie dotyczy to również null (JSON) vs nil (Ruby).
Rennex
1
Nadal przydatne w większości sytuacji.
Abram
1
Nie mogę w to uwierzyć, trzy lata później! Dzięki @Abram. :) To nie jest najbardziej eleganckie rozwiązanie na świecie, ale załatwia sprawę w mgnieniu oka.
Nick Schwaderer
4

Skorzystaj z powyższych odpowiedzi, jeśli drukujesz dla użytkowników.

Jeśli chcesz tylko wydrukować go dla siebie w konsoli, sugeruję użycie klejnotu łamiącego zamiast irb. Oprócz ładnego drukowania, pry ma również wiele innych funkcji (sprawdź rzuty poniżej)

gem install pry

I sprawdź ten railscast:

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

Abdo
źródło
3

Łatwe do zrobienia z json, jeśli ufasz, że twoje klucze są rozsądne:

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
}
grubszy
źródło
1

Używając Pry, wystarczy dodać następujący kod do swojego ~ / .pryrc:

require "awesome_print"
AwesomePrint.pry!
bartoindahouse
źródło
1

Ze wszystkich klejnotów, które wypróbowałem, show_dataklejnot działał najlepiej dla mnie, teraz używam go intensywnie do rejestrowania skrótu parametrów w Railsach prawie przez cały czas

Dr Strangelove
źródło
0

W przypadku dużych zagnieżdżonych skrótów ten skrypt może być pomocny. Drukuje zagnieżdżony hash w ładnej składni podobnej do Pythona z tylko wcięciami, aby ułatwić kopiowanie.

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

Przykładowe użycie:

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

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

Zwracana wartość to liczba (3) wszystkich wartości końcowego poziomu zagnieżdżonego skrótu.

swilgosz
źródło
0

Oto inne podejście wykorzystujące json i 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))))

(analizuje odpowiedź z np. RestClient)

Cegła suszona na słońcu
źródło
0

W Railsach

Jeśli potrzebujesz

  • hasz „ładnie wydrukowany”
  • np. w Rails.logger
  • to w szczególności działa inspectna obiektach w Hash
    • co jest przydatne, jeśli nadpisujesz / definiujesz inspectmetodę w swoich obiektach, tak jak powinieneś

... to działa świetnie! (Im większy i bardziej zagnieżdżony jest twój obiekt Hash).

logger.error my_hash.pretty_inspect

Na przykład:

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_inspectpochodzi z PrettyPrint , którego railsy zawierają domyślnie. Tak więc nie potrzeba żadnych klejnotów ani konwersji do formatu JSON.

Nie w szynach

Jeśli nie jesteś w Railsach lub jeśli powyższe zawodzi z jakiegoś powodu, spróbuj require "pp"najpierw użyć . Na przykład:

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}

Pełny przykład

pretty_inspectPrzykład Big Ol ' ed Hash z mojego projektu z zredagowanym tekstem specyficznym dla projektu z moich sprawdzonych obiektów:

{<***::******************[**:****, ************************:****]********* * ****** ******************** **** :: *********** - *** ******* *********>=>
  {: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=>
                            ["***** ******* ******",
                             "***** ******* ******"]}}}}]}}]}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ****** - ** - *********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:**]******* :: ****** - ** - *********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:***]******* :: ****** - ** - ********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:***]******* :: ****** - ** - **********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:***]******* :: ****** - ** - **********>=>
            {}},
          {<***::***********[**:*****, *************:****, *******************:***]******* :: ****** - ** - **********>=>
            {}}]}}]}}
pdobb
źródło
-4

W Railsach tablice i skróty w Rubim mają wbudowane funkcje to_json. Użyłbym JSON tylko dlatego, że jest bardzo czytelny w przeglądarce internetowej, np. Google Chrome.

Biorąc to pod uwagę, jeśli obawiasz się, że wygląda zbyt „technicznie”, prawdopodobnie powinieneś napisać własną funkcję, która zastąpi nawiasy klamrowe i kwadratowe w twoich hashach i tablicach odstępami i innymi znakami.

Wyszukaj funkcję gsub, aby znaleźć bardzo dobry sposób na zrobienie tego. Baw się różnymi postaciami i różnymi ilościami białych znaków, aż znajdziesz coś, co wygląda atrakcyjnie. http://ruby-doc.org/core-1.9.3/String.html#method-i-gsub

Sid
źródło
7
Tablice i skróty nie mają wbudowanej metody to_json, są one dodawane przez ActiveSupport z Railsów.
Tom De Leu
Jeszcze gorzej niż normalny irb / pry:{"programming_language":{"ruby":{},"python":{}}}
Darek Nędza
OP nie wykluczył Railsów
Will Sheppard