Ruby
multithreading
thread return value
concurrency
programming

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.

ruby
1worker = Thread.new do
2  sleep 1
3  21 * 2
4end
5
6result = worker.value
7puts 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.

ruby
1worker = Thread.new do
2  raise "calculation failed"
3end
4
5begin
6  worker.value
7rescue => e
8  puts e.message
9end

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.

ruby
1queue = Queue.new
2
3producer = Thread.new do
4  [10, 20, 30].each do |n|
5    queue << n * 2
6  end
7  queue << :done
8end
9
10loop do
11  item = queue.pop
12  break if item == :done
13  puts item
14end
15
16producer.join

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.

ruby
1result = nil
2
3thread = Thread.new do
4  result = "finished"
5end
6
7thread.join
8puts result

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.

ruby
1thread = Thread.new { 5 + 7 }
2
3p thread.join   # returns the Thread object
4p thread.value  # returns 12

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:

  1. use Thread#value for one final result
  2. use Queue for many results over time
  3. use Mutex only when shared mutable state is unavoidable

That keeps thread communication explicit and easier to debug.

Common Pitfalls

  • Using a shared variable when Thread#value would be simpler and safer.
  • Forgetting that join does 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.
  • 'value waits for completion and returns the block result.'
  • It also exposes exceptions, which makes failure handling cleaner.
  • Use Queue when a thread needs to emit multiple values over time.
  • Avoid shared mutable variables unless you also control synchronization carefully.

Course illustration
Course illustration

All Rights Reserved.