一位同事最近编写了一个 Ruby 脚本,该脚本通过在外部文本编辑器中打开一个包含一些初始化文本的临时文件来提示用户输入,然后在编辑器关闭后对其进行操作。此行为类似于 git 处理提交/标记编辑的方式。
require 'tempfile'
@command = options[:cmd] || "vim"
@file = Tempfile.new("buffer")
@file.write("This is the initial text in the file")
puts @file.read
@pid = Kernel.spawn("#{@command} #{@file.path}")
Process.wait(@pid)
@file.rewind
contents = @file.read
# Do stuff with "contents"
该脚本对我的一些同事来说运行良好,但是当我运行它时,它不会接收我对临时文件所做的更改:它仍然将临时文件视为具有初始化文本。我将问题追溯到它是如何读取文件的; @file.rewind
不足以让它获取更改。如果我不是通过文件对象重新读取文件,而是根据 File.new(@file.path)
创建一个新文件,我就可以让它工作。因此,我怀疑文件内容在我运行时被缓冲,但在运行时却没有。
我在 macOS 10.12.2 上使用 Ruby 2.4.0p0。这适用于在 OS X 10.11.6 上使用 Ruby 2.0.0p643 的同事,以及适用于在 Ubuntu 上使用 2.3.0-p0 的另一位同事。我确认当我使用 Ruby 2.0.0p648 时它在我的机器上不起作用,所以我怀疑这可能是由于操作系统差异而不是 Ruby 差异。
请注意,我在 Ruby 方面所做的工作很少,因此我可能遗漏了一些明显的东西。
因此我的问题是:
- 是什么导致了差异,是否在某处记录了这一点? Ruby 中是否有更改导致它被缓冲?这是操作系统的事情吗?是否在某个地方没有明确说明这是否会被缓冲?我在 IO Ruby docs 中没有看到任何明显的东西,尽管我可能找错地方了。
- 适用于跨操作系统版本的首选 Ruby 习惯用法是什么?还是关闭并重新打开方法是我的最佳选择?
最佳答案
这对我来说在与你类似的环境中工作(mac/ruby 2.4.x)。这是临时缓冲区中内容发生变化的完整脚本。
require 'tempfile'
options = {}
@command = options[:cmd] || "nano"
@file = Tempfile.new("buffer")
@file.write("This is the initial text in the file")
puts @file.read
@pid = Kernel.spawn("#{@command} #{@file.path}")
Process.wait(@pid)
@file.rewind
contents = @file.read
puts contents
我将其更改为 nano
但 vim
也能正常工作。也许你的 vim 配置有干扰?
我的测试:
- 如果临时缓冲区被编辑为说“嘿”(保存/退出)然后
puts contents
说嘿。我认为这就是您想要的。
关于Ruby 脚本看不到它创建的文件的外部更改,具体取决于它的运行位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41944482/