Skip to content

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

instance method

Ractor#send

ractor.send(msg, move: false) → self

Send a message to a Ractor’s incoming queue to be consumed by Ractor.receive.

Example
r = Ractor.new do
  value = Ractor.receive
  puts "Received #{value}"
end
r.send 'message'
# Prints: "Received: message"

The method is non-blocking (will return immediately even if the ractor is not ready to receive anything):

Example
r = Ractor.new {sleep(5)}
r.send('test')
puts "Sent successfully"
# Prints: "Sent successfully" immediately

Attempt to send to ractor which already finished its execution will raise Ractor::ClosedError.

Example
r = Ractor.new {}
r.take
p r
# "#<Ractor:#6 (irb):23 terminated>"
r.send('test')
# Ractor::ClosedError (The incoming-port is already closed)

If close_incoming was called on the ractor, the method also raises Ractor::ClosedError.

Example
r =  Ractor.new do
  sleep(500)
  receive
end
r.close_incoming
r.send('test')
# Ractor::ClosedError (The incoming-port is already closed)
# The error would be raised immediately, not when ractor will try to receive

If the obj is unshareable, by default it would be copied into ractor by deep cloning. If the move: true is passed, object is moved into ractor and becomes inaccessible to sender.

Example
r = Ractor.new {puts "Received: #{receive}"}
msg = 'message'
r.send(msg, move: true)
r.take
p msg

This prints:

Received: message
in `p': undefined method `inspect' for #<Ractor::MovedObject:0x000055c99b9b69b8>

All references to the object and its parts will become invalid in sender.

Example
r = Ractor.new {puts "Received: #{receive}"}
s = 'message'
ary = [s]
copy = ary.dup
r.send(ary, move: true)

s.inspect
# Ractor::MovedError (can not send any methods to a moved object)
ary.class
# Ractor::MovedError (can not send any methods to a moved object)
copy.class
# => Array, it is different object
copy[0].inspect
# Ractor::MovedError (can not send any methods to a moved object)
# ...but its item was still a reference to `s`, which was moved

If the object was shareable, move: true has no effect on it:

Example
r = Ractor.new {puts "Received: #{receive}"}
s = 'message'.freeze
r.send(s, move: true)
s.inspect #=> "message", still available
See also #recv #take #receive_if #to_s also in 4.1 · 4.0 · 3.4 · 3.3 · 3.2 · 3.0