我开始学习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]
答案 0 :(得分:0)
回答你的问题
有人可以解释两个版本的代码之间的区别吗?
阻止总是返回一些内容do
结束and
而{ ... }
非常重要这只是人事编程偏好。
块i有两种不同的约定 现在就告诉你,你想要订阅哪种宗教信仰。
第一宗教说
当你有single line or single line block
时你会使用花括号如果你有multi line block
,你可以使用do
和end
。
words.each { |word| puts word } # single line or single line block
words.each do |word| # multi line block
puts word
p 1
end
第二宗教说
如果你的块只是做了一些有副作用的东西,你不关心你可能会做的返回值并结束
words.each do |word|
puts word
end
如果您关心返回值,那么您将使用{...}
back_words = words.map{ |word| word.reverse }
希望我回答你的问题!!!