How to Refactor this simple Ruby algorithm
Ok, I have this ruby script which opens a file and passes each line to the line_parser method. This method simply changes tabs for a couple of spaces. Here it is:
$lines = []
def line_parser(line)
line.gsub! /\t/, ' '
$lines[$lines.length] = line
end
f = File.open(ARGV[0], 'r').each { |line| line_parser(line) }
f.close
f = File.open(ARGV[0], 'w')
$lines.each { |line| f.puts line}
f.close
As you can see it has two loops; one loop to iterate over the lines of text inside the file an place them inside of an array. And the other loop writes the file all over again with the new lines from the recently created array.
My question is simple I think: How can I refactor this snippet so that I do all the开发者_StackOverflow steps described above inside one loop only?
I know it can be done, I just have not been able to do it with my current ruby knowledge.
Thanks in advance!
out = ""
File.open(ARGV[0], "r+") do |f|
f.each do |line|
out << line.gsub(/\t/, ' ')
end
f.pos=0
f.print out
end
This just iterates over the file once but it still has to cache the file in a string before finally writing it to the file. If you want to avoid caching you will have to write to a temporary file first. Once done reading/writing you would simply delete the old file and replace it with the new temporary file by renaming it.
#!/usr/local/bin/ruby -w
src = File.read(ARGV[0])
File.open(ARGV[0], 'w') { | io |
src.each_line { | line |
io << line.gsub(/\t/, ' ')
}
}
Please note that this is actually cheated. Reading the whole file is in fact a loop. But since you are reading and then writing to the same file, I doubt you can avoid having 2 loops (one for reading and one for writing).
Can we use rubygems?
require 'rubygems'
require 'facets/file'
# Version 1
File.write('outfile', File.read('infile').tr("\t", ' '))
# Version 2
File.rewrite('inoutfile') { |str| str.tr("\t", ' ') }
精彩评论