Ruby:从内联块中断开

时间:2011-05-25 17:46:27

标签: ruby block break macruby pathname

更新

忽略以下内容。原来这是一个限制在Macruby 0.10的bug,可能特定于我的安装。如果其他人遇到问题,我会留下帖子。


我似乎误解了一些关于红宝石块的事情。我想使用PathnameFind模块的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的工作方式不同于第一个示例中的工作方式?

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

2 个答案:

答案 0 :(得分:2)

当块返回“not false”时,

Enumerable#find将执行自己的循环终止,因此:

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

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

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

答案 1 :(得分:2)

似乎使用break在OSX上使用ruby-1.8.7-p334(MRI),以及JRuby-1.6.1。