如何突破范围ruby变量ruby

时间:2016-11-17 16:19:16

标签: ruby variables scope

我使用以下代码从文件中删除行:

File.open("#{$whitelist}-tmp", "w") do |outFile|
  File.foreach("#{$whitelist}") do |li|
    outFile.puts li unless li.chomp[/\A#{instanceId}\z/]
    @comm = outFile
  end
end
FileUtils.mv(@comm, $whitelist)

它有效,但我认为这不是正确的方法,因为我必须创建一个额外的变量'@comm',只是为了从循环中传出文件名。如果我直接使用'outFile'作为FileUtils.mv的第一个参数,我得到一个未定义的变量错误。

那么,我应该怎么做呢?

提前致谢。

2 个答案:

答案 0 :(得分:2)

Doc File.open

  

如果给出了可选的代码块,它将作为参数传递打开的文件,当块终止时,File对象将自动关闭。 将从File.open返回块的值。

所以我们可以这样做

file = File.open("#{$whitelist}-tmp", "w") do |outFile|
  File.foreach("#{$whitelist}") do |li|
    outFile.puts li unless li.chomp[/\A#{instanceId}\z/]
  end

  outFile # return value of the block
end

FileUtils.mv(file, $whitelist)

更新

我错过了什么或者这段代码只是过滤并重写文件?如果是这样,它可以大大简化。

filename = $whitelist

content = File.readlines(filename)
filtered = content.grep(/\A#{instanceId}\Z/)
File.write(filename, filtered)

答案 1 :(得分:1)

最简单的方法是在使用它的块之前分配一个包含文件名的变量:

tempFile = "#{$whitelist}-tmp"
File.open(tempFile, "w") do |outFile|
  File.foreach("#{$whitelist}") do |li|
    outFile.puts li unless li.chomp[/\A#{instanceId}\z/
  end
end
FileUtils.mv(tempFile, $whitelist)