2

アップデート

以下は無視してください。これはMacruby0.10に限定されたバグであり、おそらく私のインストールに固有のバグであることが判明しました。他の誰かが問題にぶつかった場合に備えて、私は投稿を残します。


私はルビーブロックについて何かを誤解しているようでした。PathnameまたはFindモジュールを使用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 = 

...探しているパスを1つだけ生成しますが、どちらも値を生成しません。

次の両方の理由で、テストが機能することを知っています。

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

...期待どおりに動作します。

最初の例のように動作breakしないのはなぜですか?find

より一般的には、私はこの状況に正しいルビーテクニック/イディオムを使用していますか?

4

2 に答える 2

2

Enumerable#findブロックが「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 に答える