Forum: Ruby Write output to multiple files

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Abfecec49e4871d38bfeedf7590c06ed?d=identicon&s=25 Milo Thurston (milo)
on 2009-04-23 16:20
I have encountered something I thought would be trivial but I can't
quite get it to work properly. I have a load of data that is stored in
various locations and need to create several files, one for each
location, each containing the data in that location. Getting an array of
objects containing the file name and location is easy, so I was thinking
along the lines of this pseudocode:

data.each do |d|
  output_filename = "#{d.location}.txt"
  if !File.exists?(output_filename)
    # create it and write d.file_name to it
  else
    # simply write d.file_name to it
  end
end
# close all open files

The locations of the data are numerical ids so I could expect filenames
like 1.txt, 2.txt and so on, and I have also sorted them before
processing so that they could be opened and filled sequentially. But, it
is not clear to me how to properly manage the file handles so any
suggestions would be welcome.
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-04-23 18:45
(Received via mailing list)
On 23.04.2009 16:20, Milo Thurston wrote:
>     # create it and write d.file_name to it
> suggestions would be welcome.
If I understood you properly:

# untested
last_name = nil
io = nil
begin
   data.sort_by {|d| d.location}.each do |d|
     output_filename = "#{d.location}.txt"

     unless output_filename == last_name
       io.close rescue nil
       io = File.open(output_filename, "a")
     end

     io.puts d.file_name
ensure
   io.close rescue nil
end


If you want to keep 'data' unsorted you might want to store IO objects
in a Hash, e.g.

files = Hash.new {|h,k| h[k] = File.open(k, "a")}
begin
   data.each do |d|
     output_filename = "#{d.location}.txt"
     files[output_filename].puts d.file_name
   end
ensure
   files.each do |k,io|
     io.close rescue nil
   end
end

Kind regards

  robert
Abfecec49e4871d38bfeedf7590c06ed?d=identicon&s=25 Milo Thurston (milo)
on 2009-04-23 18:48
Robert Klemme wrote:

> If I understood you properly:
>
> # untested
> last_name = nil
> io = nil
> begin
>    data.sort_by {|d| d.location}.each do |d|
>      output_filename = "#{d.location}.txt"
>
>      unless output_filename == last_name
>        io.close rescue nil
>        io = File.open(output_filename, "a")
>      end
>
>      io.puts d.file_name
> ensure
>    io.close rescue nil
> end


Yes, that looks like just the job, thanks. I was trying something
similar but without the begin/ensure/end block and that is presumably
why I was having difficulty.
This topic is locked and can not be replied to.