How can I return a value from a thread in Ruby?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Ruby, a thread can return a value, but not in the same direct way as a normal method call. The most idiomatic approach is to let the thread finish and then read its result through Thread#value. If you need streaming results, coordination between multiple threads, or failure handling, queues and explicit synchronization become more appropriate.
Use Thread#value for the Normal Case
Ruby threads remember the result of the block they run. Calling value on the thread waits for completion and then returns that result.
This is the cleanest answer when you have one background computation and one final result.
value Also Propagates Exceptions
One reason Thread#value is better than shared variables is that it keeps failure visible. If the thread raises an exception, calling value will surface that exception instead of silently returning nothing useful.
That makes error handling much more honest than manually writing to a global variable.
Use a Queue for Multiple Results
If a thread produces more than one value over time, a queue is a better fit than Thread#value. A queue lets the producer push results as they become available and lets the consumer read them safely.
This pattern works well when the thread is not just computing one final answer.
Avoid Shared Mutable Variables When Possible
It is possible to write into an outer variable from a thread, but that is usually the weakest design because the code becomes harder to reason about and easier to race.
This can work in tiny examples, but it does not scale well once multiple writers or more complex control flow appear. Prefer value, Queue, or other synchronization primitives.
Know the Difference Between join and value
join waits for the thread to finish and returns the thread object. value waits and returns the result of the block.
If your goal is the computed result, value is the more direct API.
Think About Thread Lifetime Too
Returning a value only works if the thread is allowed to finish. In longer-running programs, it is worth deciding whether the caller should block indefinitely, use a timeout around coordination, or cancel the work by a higher-level design. The return mechanism is only one part of thread management.
Choose the Right Pattern
Use these rules:
- use
Thread#valuefor one final result - use
Queuefor many results over time - use
Mutexonly when shared mutable state is unavoidable
That keeps thread communication explicit and easier to debug.
Common Pitfalls
- Using a shared variable when
Thread#valuewould be simpler and safer. - Forgetting that
joindoes not return the thread's computed result. - Ignoring exceptions inside threads and losing failure information.
- Using queues without a clear completion signal such as
:done. - Adding threads when the task does not actually benefit from concurrent execution.
Summary
- The idiomatic way to get a Ruby thread result is
Thread#value. - '
valuewaits for completion and returns the block result.' - It also exposes exceptions, which makes failure handling cleaner.
- Use
Queuewhen a thread needs to emit multiple values over time. - Avoid shared mutable variables unless you also control synchronization carefully.

