Skip to content

End of Life Ruby 3.2 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →

class method

Ractor.receive_if

Ractor.receive_if {|msg| block } → msg

Receive only a specific message.

Instead of Ractor.receive, Ractor.receive_if can provide a pattern by a block and you can choose the receiving message.

Example
r = Ractor.new do
  p Ractor.receive_if{|msg| msg.match?(/foo/)} #=> "foo3"
  p Ractor.receive_if{|msg| msg.match?(/bar/)} #=> "bar1"
  p Ractor.receive_if{|msg| msg.match?(/baz/)} #=> "baz2"
end
r << "bar1"
r << "baz2"
r << "foo3"
r.take

This will output:

Example
foo3
bar1
baz2

If the block returns a truthy value, the message will be removed from the incoming queue and returned. Otherwise, the message remains in the incoming queue and the following received messages are checked by the given block.

If there are no messages left in the incoming queue, the method will block until new messages arrive.

If the block is escaped by break/return/exception/throw, the message is removed from the incoming queue as if a truthy value had been returned.

Example
r = Ractor.new do
  val = Ractor.receive_if{|msg| msg.is_a?(Array)}
  puts "Received successfully: #{val}"
end

r.send(1)
r.send('test')
wait
puts "2 non-matching sent, nothing received"
r.send([1, 2, 3])
wait

Prints:

2 non-matching sent, nothing received
Received successfully: [1, 2, 3]

Note that you can not call receive/receive_if in the given block recursively. It means that you should not do any tasks in the block.

Example
Ractor.current << true
Ractor.receive_if{|msg| Ractor.receive}
#=> `receive': can not call receive/receive_if recursively (Ractor::Error)
See also #receive_if .receive .recv .new also in 3.4 · 3.3 · 3.1 · 3.0