То, что вы видите здесь, это состояние гонки.Вы пытаетесь прочитать переменную потока до того, как тело потока будет выполнено .
Сравните следующее:
w = Whatever.new
w.apple
# => nil
w = Whatever.new
sleep 0.1
w.apple
# => "whatever"
Независимо от того, запускается ли тело потока во времени с Whatever.new.apple
, это довольно случайно, кажется, это происходит в 0,1% времени для меня,но это, вероятно, отличается на других машинах
1000.times.
map { Whatever.new.apple }.
each_with_object(Hash.new(0)) { |val, memo| memo[val] += 1 }
# => {nil=>999, "whatever"=>1}
2000.times.
map { Whatever.new.apple }.
each_with_object(Hash.new(0)) { |val, memo| memo[val] += 1 }
# => {nil=>1998, "whatever"=>2}
(примечание: я не могу попробовать с большим числом итераций, потому что большое количество порождения потока приводит к исчерпанию ресурсов моего IRB)
Это относится к тому, что я слышал, описал как «правило асинхронности номер один», а именно, что вы не можете получить возвращаемое значение асинхронного метода из синхронного.Обычный способ справиться с этим - с помощью «обратного вызова», который Ruby может делать в виде yield
/ blocks.
Я рекомендую поискать учебник о том, как выполнять асинхронное программирование в Ruby.