【问题标题】:Weird File.open behavior when using different closure types in Ruby在 Ruby 中使用不同闭包类型时的奇怪 File.open 行为
【发布时间】: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”问题。

标签: ruby windows


【解决方案1】:

回答你的问题

有人能解释一下这两个版本的代码的区别吗?

  • 块总是返回一些东西所以do结束and{ ... }并不重要这只是人员编程偏好。

  • 我要分配的块有两种不同的约定 现在由您决定,您要订阅哪种宗教。

第一个宗教这么说

当你有single line or single line block 时,你会使用花括号;如果你有multi line block,你会使用doend

words.each { |word| puts word }  # single line or single line block

words.each do |word|  # multi line block
  puts word
  p 1
end

第二宗教这么说

如果你的块只是做了一些有副作用的事情,而你不关心你可能把 do 和 end 的返回值

words.each do |word|
  puts word
end

如果你确实关心返回值,你会使用 { ... }

back_words = words.map{ |word| word.reverse }

希望我回答你的问题!!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多