красивая печать в файл в ruby

Я пытаюсь красиво напечатать хэш в файл.

Я пробовал перенаправления unix [постепенно добавлял к нему разные флаги]:

`echo #{pp  mymap} | tee summary.out 2>&1`

и файловый ввод-вывод

 my_file = File.new(@dir_+"/myfile.out",'w+')          
 my_file.puts `#{pp get_submap_from_final(all_mapping_file,final_map)}`

Он всегда выводит на консоль и не записывает в файл.

Также должен быть более простой способ записи в файл в одну строку в ruby? вместо того, чтобы делать File.new, а затем писать в файл?


person codeObserver    schedule 10.02.2012    source источник


Ответы (6)


Использование обратных кавычек здесь вызывает недоумение, поскольку они используются для выполнения команд оболочки.

Что вы, вероятно, имеете в виду:

File.open(@dir_+"/myfile.out",'w+') do |f|
  f.write(pp(get_submap_from_final(all_mapping_file,final_map)))
end

Метод pp всегда записывает в консоль, поэтому вы можете увидеть его и все еще записать.

person tadman    schedule 10.02.2012
comment
Я думаю, что даже обратные кавычки #{} интерпретируются рубиновым интерпретатором. Код, который вы дали, по-прежнему выводится на консоль, но не записывается в файл :( - person codeObserver; 11.02.2012
comment
Это интерпретируется, да, но зачем вам отправлять оцененный результат в оболочку? Это та часть, которая не имеет смысла. Помните, что обратные кавычки очень похожи на system. - person tadman; 11.02.2012
comment
это было потому, что я думал, что смогу добиться перенаправления в файл, используя › и 2›&1 .. что не сработало, поэтому я ошибся, я думаю:) .. Как мне получить перенаправление pp в файл, начиная с f.write тоже не получается. - person codeObserver; 11.02.2012

Как насчет (не используя pp напрямую):

File.open("myfile.out","w+") do |f|
  f.puts mymap.inspect
end

Или даже перенаправить стандартный вывод для файла

file = File.open("myfile.out", "w+)

old_stdout = STDOUT

$stdout = STDOUT = file

pp get_submap_from_final(all_mapping_file,final_map)

$stdout = STDOUT = old_stdout
person Edu    schedule 10.02.2012
comment
спасибо Эду. inspect выглядит элегантно, но, к сожалению, не добавляет новую строку после каждого значения ключа. Не могли бы вы объяснить пример подхода stdout. получаю динамическое присваивание констант $stdout=STDOUT=file error..увы тоже не совсем понимаю что происходит в коде :)... - person codeObserver; 11.02.2012

Выполнение чего-то похожего на то, что предложил Эду, и Как мне перенаправить stderr и stdout в файл для скрипта Ruby? помогло.

Вот как новый код похож на:

$stdout.reopen(@dir_+"/my_file.out",'w+')
puts "All metrics are:"
pp final_map
$stdout=STDOUT

Все равно было бы интересно узнать, почему операторы перенаправления > и 2>&1 в обратных галочках не работают

person codeObserver    schedule 11.02.2012

Вот расширение сообщения выше, чтобы также красиво распечатать вывод json в файл.

require "pp"
require "json"

class File
  def pp(*objs)
    objs.each {|obj|
      PP.pp(obj, self)
    }
    objs.size <= 1 ? objs.first : objs
  end
  def jj(*objs)
    objs.each {|obj|
      obj = JSON.parse(obj.to_json)
      self.puts JSON.pretty_generate(obj)
    }
    objs.size <= 1 ? objs.first : objs
  end
end

test_object = { :name => { first: "Christopher", last: "Mullins" }, :grades => [ "English" => "B+", "Algebra" => "A+" ] }

test_json_object = JSON.parse(test_object.to_json)

File.open("log/object_dump.txt", "w") do |file|
  file.pp(test_object)
end

File.open("log/json_dump.txt", "w") do |file|
  file.jj(test_json_object)
end
person Christopher Mullins    schedule 23.12.2012

Учитывая mymap из вопроса, вы можете использовать гем "show_data", который предоставляет два метода: show_data и format_data. Последний создает «красиво напечатанную» строку своего аргумента, которую затем можно передать любому методу вывода.

require 'show_data'

$stderr.puts format_data(mymap)

Например:

myhash = { 'owners' => 21050, 'users' => 16877, 'portfolios' => 583, 
           'properylists' => 0, 'properties' => 29504, 'units' => 62688, 
           'tenants' => 85856 }
$stderr.puts format_data(myhash)

на STDERR:

 {      'owners' => 21050,
         'users' => 16877,
    'portfolios' => 583,
  'properylists' => 0,
    'properties' => 29504,
         'units' => 62688,
       'tenants' => 85856
}
person aks    schedule 23.04.2014

person    schedule
comment
Просто чтобы уточнить, в приведенном выше примере значение self будет записано в файл. Если вы хотите написать что-то еще. это будет PP.pp('записать это в файл', f) - person Usman; 14.04.2014