Maintenance Ruby 3.4 gets fixes, but no new features. Switch to Ruby 4.0 →
Ractor#take
# File tmp/rubies/ruby-3.4.1/ractor.rb, line 710
def take
__builtin_cexpr! %q{
ractor_take(ec, RACTOR_PTR(self))
}
end
Get a message from the ractor’s outgoing port, which was put there by Ractor.yield or at ractor’s termination.
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.
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.
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:
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