NoobException
NoobException

Reputation: 666

Ruby execution order in multithreaded program

In prep for hurricane irma I wrote a quick trash script to download a bunch of exercises off exercism.io. It works, but there's an error at the call to threads.each that I don't understand, all the code up until threads.each is synchronous if I understand correctly, so I'm not sure what the best way to fix is.:

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

It's interesting to me because I get the error but the program still runs as expected, so I'm sure I'm not writing this properly.

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)

Upvotes: 1

Views: 90

Answers (1)

fgb
fgb

Reputation: 18569

Use next instead of break so that threads is still set if any exercises are blank. break will cancel the whole loop, but next will skip only the current iteration.

Then some threads could still be nil if their exercise is blank, because no thread has started for them. You can use threads.compact.each(&:join) to skip these nil values.

Or if you need the break, then add to threads inside the loop like:

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

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

Upvotes: 1

Related Questions