2

更新

忽略以下。结果证明这是一个仅限于 Macruby 0.10 的错误,并且可能特定于我的安装。我会留下帖子以防其他人遇到问题。


我似乎误解了关于红宝石块的一些东西。我想使用PathnameorFind模块find在特定目录树中定位特定文件。但是,我无法让提供的块find返回任何值。

从此:

n= (1..10).each {|i| break i if i > 5} 
puts "n = #{n}" #=> n=6

...有效(并且是一种常见的结构)我希望:

starting_directory= #... a directory path
file_name_I_want_to_find= #... a file name e.g. my_file.txt
pd=Pathname.new(starting_directory)
path=pd.find{|p| break p if p.basename.to_s==file_name_I_want_to_find } 
puts "path = #{path}" #=> path = 

... 或者:

path=Find.find(starting_directory) {|p| break p if p.include?(file_name_I_want_to_find) } 
puts "path = #{path}" #=> path = 

... 只会产生一条寻求的路径,但根本不会产生任何价值。

我知道我的测试有效,因为以下两项:

pd.find{|p| puts p if p.basename.to_s==file_name_I_want_to_find } 
#=> /path/to/file_name_I_want_to_find

Find.find(starting_directory) {|p| puts p if p.include?(file_name_I_want_to_find) } 
#=> /path/to/file_name_I_want_to_find

...按预期工作。

为什么不像breakfind一个例子那样工作?

更一般地说,我是否在这种情况下使用了正确的红宝石技术/习语?

4

2 回答 2

2

Enumerable#find当块返回“not false”时,将执行自己的循环终止,因此:

pd.find { |p| p.basename.to_s == file_name_I_want_to_find }

无论您的构造是否真的有效(似乎),您实际上都不知道哪个方法最终将控制权交给了块,所以我认为可能很难使用 break 并继续强制核心 API 元素上的行为。我怀疑它们用作块控制流表达式的目的主要是在实现中而不是在 API 边界上。

所以,“不”,这并不是最好的 Ruby 习语。您应该直接使用 API。您尝试做的所有事情都有一个直接的核心 API(和某种功能)实现,而无需构建您自己的命令式实现。

于 2011-05-25T18:35:48.877 回答
2

似乎使用break适用于 OSX 上的 ruby​​-1.8.7-p334 (MRI) 以及 JRuby-1.6.1。

于 2011-05-25T20:11:17.377 回答