Pregunta

Update

Ignore the following. It turned out to be a bug restricted to Macruby 0.10 and probably specific to my install. I'll leave the post in case anyone else hits the problem.


I seemed to misunderstood something about ruby blocks. I wanted to use the Pathname or Find module's find to locate a specific file within a specific directory tree. However, I cannot get the block provided to find to return any value.

Since this:

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

... works (and is a common construction) I expected that either:

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 = 

... or:

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

... would produce just the one sought path but neither produces a value at all.

I know my test works because both of the following:

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

... work as expected.

Why doesn't break with find work the way it does in the first example?

More generally, am I using the correct ruby technique/idiom for this circumstance?

¿Fue útil?

Solución

It seems that using break works on ruby-1.8.7-p334 (MRI) on OSX, as well as JRuby-1.6.1.

Otros consejos

Enumerable#find will do its own loop termination when the block returns "not false", so:

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

Regardless of whether your construct actually works or not (it seems to) you don't actually know which method ended up yielding control to the block, so I think it may be difficult to use break and continue to force behavior on core API elements. I suspect their use as block control flow expressions is intended mainly within an implementation rather than over API boundaries.

So, "no", that's not really the best Ruby idiom. You should use the API directly. Everything you are trying to do has a direct core API (and sort-of functional) realization without constructing your own imperative implementation.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top