如何重构这个简单的Ruby算法

时间:2011-08-28 20:48:32

标签: ruby algorithm refactoring

好的,我有这个ruby脚本打开一个文件并将每一行传递给 line_parser 方法。此方法只是更改几个空格的选项卡。这是:

$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

你可以看到它有两个循环; 一个循环迭代文件内的文本行,将它们放在数组中。另一个循环使用最近创建的数组中的 new 行重新写入文件。

我认为我的问题很简单: 如何重构此代码段,以便我只在一个循环中执行上述所有步骤?

我知道可以做到,我只是无法用我目前的红宝石知识做到这一点。

提前致谢!

3 个答案:

答案 0 :(得分:2)

#!/usr/local/bin/ruby -w

src = File.read(ARGV[0])

File.open(ARGV[0], 'w') { | io |
  src.each_line { | line |
    io << line.gsub(/\t/, '  ')
  }
}

请注意,这实际上是被骗了。读取整个文件实际上是一个循环。 但既然你正在阅读然后写同一个文件,我怀疑你可以避免 2个循环(一个用于阅读,一个用于写入)。

答案 1 :(得分:2)

out = ""
File.open(ARGV[0], "r+") do |f|
  f.each do |line|
    out << line.gsub(/\t/, '  ')
  end
  f.pos=0
  f.print out
end

这只是迭代文件一次,但它仍然必须在最终将文件写入文件之前将文件缓存在字符串中。如果要避免缓存,则必须先写入临时文件。完成读/写后,您只需删除旧文件,并通过重命名将其替换为新的临时文件。

答案 2 :(得分:1)

我们可以使用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", ' ') }