Skip to content

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

class method

Ractor.select

(*::Ractor ractors, ?move: ::boolish, ?yield_value: untyped) -> [ ::Ractor | ::Symbol, untyped ]
Ractor.select(*ractors, [yield_value:, move: false]) → [ractor or symbol, obj]

Wait for any ractor to have something in its outgoing port, read from this ractor, and then return that ractor and the object received.

Example
r1 = Ractor.new {Ractor.yield 'from 1'}
r2 = Ractor.new {Ractor.yield 'from 2'}

r, obj = Ractor.select(r1, r2)

puts "received #{obj.inspect} from #{r.inspect}"
# Prints: received "from 1" from #<Ractor:#2 test.rb:1 running>
# But could just as well print "from r2" here, either prints could be first.

If one of the given ractors is the current ractor, and it is selected, r will contain the :receive symbol instead of the ractor object.

Example
r1 = Ractor.new(Ractor.current) do |main|
  main.send 'to main'
  Ractor.yield 'from 1'
end
r2 = Ractor.new do
  Ractor.yield 'from 2'
end

r, obj = Ractor.select(r1, r2, Ractor.current)
puts "received #{obj.inspect} from #{r.inspect}"
# Could print: received "to main" from :receive

If yield_value is provided, that value may be yielded if another ractor is calling take. In this case, the pair [:yield, nil] is returned:

Example
r1 = Ractor.new(Ractor.current) do |main|
  puts "Received from main: #{main.take}"
end

puts "Trying to select"
r, obj = Ractor.select(r1, Ractor.current, yield_value: 123)
wait
puts "Received #{obj.inspect} from #{r.inspect}"

This will print:

Trying to select
Received from main: 123
Received nil from :yield

move boolean flag defines whether yielded value will be copied (default) or moved.

See also .recv .shareable? .receive_if .store_if_absent also in 4.1 · 4.0 · 3.3 · 3.2 · 3.1 · 3.0