【发布时间】:2014-10-10 11:12:22
【问题描述】:
我开始学习 Chef 来管理我们的服务器,并且在 Ruby 中偶然发现了一个非常奇怪(在我看来)的行为。我不了解 Ruby,所以这可能只是我的一个误解。
我得到的error是
`delete': Permission denied - [some path]/metadata.json (Errno::EACCES)
既然我确定这实际上与权限无关,接下来的逻辑就是检查文件锁定。在深入挖掘了相关代码后,我发现有一种方法可以为每个文件生成校验和。
def checksum_file(file, digest)
File.open(file, 'rb') { |f| checksum_io(f, digest) }
end
def checksum_io(io, digest)
while chunk = io.read(1024 * 8)
digest.update(chunk)
end
digest.hexdigest
end
发现后,我搜索了一下,发现了一个关于在 Ruby 中关闭文件的answer,看起来代码实际上很好……但事实并非如此。我试图将方法更改为 “块格式”,它没有错误地工作:
def checksum_file(file, digest)
File.open(file, 'rb') do |f|
checksum_io(f, digest)
end
end
有人能解释一下这两个版本的代码的区别吗?
-- 编辑--
这个问题似乎只出现在 Windows 中,也许只有在使用 ChefDK 0.3.0 提供的 ruby 时才会出现:
ruby 2.0.0p451 (2014-02-24) [i386-mingw32]
【问题讨论】:
-
the code was actually fine, but it wasn't- 去过那里。 -
这两种方法是相同的。
{}和do end块之间没有语义差异 -
我添加了更多有问题的代码,特别是围绕正在发生的
IO#read方法 -
根据the pickaxe,“它们具有不同的优先级:大括号比 do/end 对绑定得更紧密”。 我不知道这将如何解释奇怪的行为,但可能会给比我更聪明的人一个提示。 :)
-
@Didistis(或其他任何可以的人),请编辑问题和/或标记它以强调这发生在 Windows 上。在有人尝试在 POSIX 操作系统上重新创建它之前,我们不知道这是一个“ruby”问题还是“ruby on windows”问题。