2017-09-09 7 views
1

ハリケーンirmaの準備で、私はexerciseism.ioから一連のエクササイズをダウンロードするためのクイックゴミスクリプトを作成しました。それは動作しますが、私は理解していないthreads.eachへの呼び出しでエラーがあります、私は正しく理解する場合、threads.eachが同期しているまでのすべてのコードは、どのような最善の方法を修正するか分からない。:マルチスレッドプログラムのRuby実行順序

rb:14:in '<main>': undefined method 'each' for nil:NilClass (NoMethodError)

私はエラーを取得するが、期待通りにプログラムがまだ実行されますので、私は、私はこれを適切に書いていないよ確信しているので、それは私には興味深いです。

language = ARGV[0] 

exercises = `exercism list #{@language}`.split("\n") 

threads = exercises.map do |exercise| 
    break if exercise == '' 

    Thread.new do 
    system("exercism fetch #{language} #{exercise}") 
    end 
end 

threads.each(&:join) 

答えて

1

利用next代わりのbreakので、任意の演習が空白の場合threadsがまだ設定されていること。 breakはループ全体をキャンセルしますが、nextは現在の反復のみをスキップします。

スレッドが開始されていないため、練習が空白の場合はまだnilになるスレッドもあります。 threads.compact.each(&:join)を使用して、これらの値をスキップしてnilにすることができます。

それともbreakが必要な場合は、その後のようなループ内threadsに追加します。私たちは、 `「」`ヒットたら、これ以上の練習がないことを知っている。この特定のケースでは

threads = [] 
exercises.each do |exercise| 
    break if exercise == '' 

    threads << Thread.new do 
    system("exercism fetch #{language} #{exercise}") 
    end 
end 
+0

は、それだけの指示ですその後。 – NoobException

+1

@NoobException 'break'は' threads'への代入を防ぐので、 'next'で置き換えるか、代入を取り除き、代わりにループ内のスレッドに追加する必要があります。 – fgb

+0

しかし、ループ内での追加についてのあなたのコメントは理にかなっています。答えがあれば、それを正しいものとしてマークします。 – NoobException