Ractor lets Ruby run code truly at the same time on multiple CPU cores. This helps programs run faster by doing many things together.
Ractor for true parallelism in Ruby
ractor = Ractor.new do # code to run in parallel result = some_work Ractor.yield(result) # send result back end value = ractor.take # get result from ractor
Ractor.new creates a new parallel task.
Use Ractor.yield to send data back from inside the ractor.
ractor = Ractor.new do 5 * 5 end result = ractor.take puts result
ractor = Ractor.new do sum = 0 (1..10).each { |n| sum += n } sum end puts ractor.take
ractor = Ractor.new do Ractor.yield("Hello from ractor") end message = ractor.take puts message
This program shows how to use a ractor to calculate squares of numbers from 1 to 5 in parallel. The main program prints messages before and after getting the result.
puts "Main program starts" # Create a ractor to calculate squares of numbers square_ractor = Ractor.new do squares = [] (1..5).each do |number| squares << number * number end squares end # Main program continues while ractor works puts "Doing other work in main thread..." # Get result from ractor result = square_ractor.take puts "Squares calculated in ractor: #{result}" puts "Main program ends"
Time complexity depends on the task inside the ractor, but using ractors can speed up multi-core processing.
Space complexity includes the memory used by the ractor and its data.
Common mistake: Trying to share mutable objects between ractors causes errors. Use message passing instead.
Use ractors when you need true parallelism. For simple concurrency, threads might be enough.
Ractors let Ruby run code truly in parallel on multiple CPU cores.
Use Ractor.new to create a parallel task and Ractor.yield or take to communicate.
Ractors help speed up programs by doing work at the same time safely.
Practice
Ractor in Ruby?Solution
Step 1: Understand Ractor's role
Ractor is designed to enable true parallel execution in Ruby, using multiple CPU cores.Step 2: Compare options
Options A, B, and C do not relate to parallelism or CPU core usage.Final Answer:
To run code truly in parallel on multiple CPU cores -> Option AQuick Check:
Ractor = true parallelism [OK]
- Confusing Ractor with threads
- Thinking Ractor is for UI or database
- Assuming Ractor runs code sequentially
Solution
Step 1: Identify Ractor creation syntax
Ractor is created usingRactor.newwith a block of code to run in parallel.Step 2: Eliminate other options
Thread, Process, and Fiber are different concurrency tools, not Ractor.Final Answer:
Ractor.new { puts 'Hello from Ractor' } -> Option AQuick Check:
Use Ractor.new to create Ractors [OK]
- Using Thread.new instead of Ractor.new
- Confusing Process.spawn with Ractor
- Using Fiber.new which is cooperative, not parallel
r = Ractor.new { 5 * 5 }
result = r.take
puts resultSolution
Step 1: Understand Ractor block execution
The block{ 5 * 5 }runs inside the Ractor and returns 25.Step 2: Use
taketo get the resultr.takereceives the value returned by the Ractor block, which is 25.Final Answer:
25 -> Option DQuick Check:
Ractor returns 25, take receives it [OK]
- Expecting string '5 * 5' instead of calculation
- Confusing take with yield
- Assuming nil or error without communication
r = Ractor.new do Ractor.yield 10 20 end puts r.take puts r.take
Solution
Step 1: Understand Ractor.yield and r.take
Ractor.yield sends a value to the main thread, and r.take receives it. The first r.take gets 10.Step 2: Analyze second r.take call
The block returns 20 after yield, which is the final value. The second r.take gets 20. After that, the Ractor is closed. A third r.take would cause error, but here only two calls are made, so no error.Step 3: Check the code carefully
Both r.take calls are valid; no error occurs.Final Answer:
No error, code runs fine -> Option CQuick Check:
Ractor.yield and take work twice safely [OK]
- Thinking Ractor.yield is invalid inside Ractor
- Expecting error on second take call
- Assuming Ractor.new needs arguments
Solution
Step 1: Split the range correctly
We want two Ractors, one summing 1 to 50, the other 51 to 100.Step 2: Check the operations and combining results
r1 = Ractor.new { (1..50).sum } r2 = Ractor.new { (51..100).sum } puts r1.take + r2.take sums each half and adds results correctly. r1 = Ractor.new { (1..100).sum } r2 = Ractor.new { (1..100).sum } puts r1.take + r2.take sums full range twice (wrong). r1 = Thread.new { (1..50).sum } r2 = Thread.new { (51..100).sum } puts r1.value + r2.value uses Thread, not Ractor. r1 = Ractor.new { (1..50).reduce(:+) } r2 = Ractor.new { (51..100).reduce(:+) } puts r1.take * r2.take multiplies sums instead of adding.Final Answer:
r1 = Ractor.new { (1..50).sum } r2 = Ractor.new { (51..100).sum } puts r1.take + r2.take -> Option BQuick Check:
Split range, sum halves, add results [OK]
- Using Thread instead of Ractor
- Summing full range twice
- Multiplying sums instead of adding
Ready to prove it?
Pass the test and this pattern moves unknown
