Skip to content

Maintenance Ruby 3.4 gets fixes, but no new features. Switch to Ruby 4.0 →

instance method

Ractor#take

() -> untyped
ractor.take → msg

Get a message from the ractor’s outgoing port, which was put there by Ractor.yield or at ractor’s termination.

Example
r = Ractor.new do
  Ractor.yield 'explicit yield'
  'last value'
end
puts r.take #=> 'explicit yield'
puts r.take #=> 'last value'
puts r.take # Ractor::ClosedError (The outgoing-port is already closed)

The fact that the last value is also sent to the outgoing port means that take can be used as an analog of Thread#join (“just wait until ractor finishes”). However, it will raise if somebody has already consumed that message.

If the outgoing port was closed with close_outgoing, the method will raise Ractor::ClosedError.

Example
r = Ractor.new do
  sleep(500)
  Ractor.yield 'Hello from ractor'
end
r.close_outgoing
r.take
# Ractor::ClosedError (The outgoing-port is already closed)
# The error would be raised immediately, not when ractor will try to receive

If an uncaught exception is raised in the Ractor, it is propagated by take as a Ractor::RemoteError.

Example
r = Ractor.new {raise "Something weird happened"}

begin
  r.take
rescue => e
  p e              #  => #<Ractor::RemoteError: thrown by remote Ractor.>
  p e.ractor == r  # => true
  p e.cause        # => #<RuntimeError: Something weird happened>
end

Ractor::ClosedError is a descendant of StopIteration, so the termination of the ractor will break out of any loops that receive this message without propagating the error:

Example
r = Ractor.new do
  3.times {|i| Ractor.yield "message #{i}"}
  "finishing"
end

loop {puts "Received: " + r.take}
puts "Continue successfully"

This will print:

Received: message 0
Received: message 1
Received: message 2
Received: finishing
Continue successfully
See also #send #to_s #recv also in 3.3 · 3.2 · 3.1 · 3.0