pretty print to a file in ruby
Asked Answered
L

7

29

I am trying to pretty print a hash to a file.

I tried unix redirects [added different flags to it incrementally] :

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

and File IO

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

It always prints to console and doesnt write to a file.

Also there has to be an easier way to write to file in one line in ruby ? instead of doing File.new and then writing to a file ?

Loosen answered 10/2, 2012 at 21:15 Comment(0)
H
58
require 'pp'

File.open("test.txt","w") do |f|
  PP.pp(self,f)
end
Hsu answered 7/4, 2012 at 15:50 Comment(1)
Just to clarify, In above example, value of "self" would be written to the file. If you want to write something else. it would be PP.pp('write this to file', f)Moyna
K
2

The use of backticks here is perplexing since those are used for executing shell commands.

What you probably mean is:

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

The pp method always writes to the console so you might see it and still have it written.

Kyne answered 10/2, 2012 at 21:23 Comment(3)
I think even in backticks #{} get interpreted by ruby interpreter. The code you gave still outputs to console but doesnt write to the file :(Loosen
It gets interpreted, yes, but why would you want to send the evaluated result to the shell? That's the part that makes no sense. Remember backticks are very similar to system.Kyne
that was because I thought I would be able to achieve the redirect to a file using > and 2>&1 .. which didnt work so I was wrong I guess :).. How do I get pp redirect to a file since f.write also doesnt make it happen.Loosen
C
1

What about (not using pp directly):

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

Or even redirect stdout for the file

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
Charitacharitable answered 10/2, 2012 at 21:26 Comment(1)
thankx Edu. inspect looks elegant but unfortunately it doesnt put new line after each key value. Can you please explain the stdout approach example. I get dynamic constant assignment $stdout = STDOUT = file error .. alas also don't quite understand what is happening in the code :)...Loosen
L
0

Doing something similar to what Edu suggested and How do I redirect stderr and stdout to file for a Ruby script? helped.

Here is how the new code is similar to:

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

Would still be interested to know why redirection operators > , and 2>&1 in back-ticks doesn't work

Loosen answered 11/2, 2012 at 1:12 Comment(0)
T
0
require 'pp'

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

File.open('output','w') do |file|
  file.pp mymap
end
Thrawn answered 10/10, 2012 at 23:18 Comment(0)
F
0

Here's an expansion to the post above to also to pretty print json output to a file.

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
Fecundity answered 23/12, 2012 at 4:15 Comment(0)
T
0

Given the mymap from the question, you can use the "show_data" gem, which provides two methods: show_data and format_data. The latter produces a "pretty-printed" string of its argument which can then be fed to any output method.

require 'show_data'

$stderr.puts format_data(mymap)

For example:

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

on STDERR:

 {      'owners' => 21050,
         'users' => 16877,
    'portfolios' => 583,
  'properylists' => 0,
    'properties' => 29504,
         'units' => 62688,
       'tenants' => 85856
}
Tanny answered 23/4, 2014 at 0:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.