Channel Directions in Ruby
Ruby’s approach to channel-like communication is different from Go’s, but we can achieve similar functionality using Ruby’s Thread and Queue classes. Here’s an equivalent implementation:
require 'thread'
# This `ping` method only accepts a queue for sending
# values. It would be a runtime error to try to
# receive from this queue within this method.
def ping(pings, msg)
pings.push(msg)
end
# The `pong` method accepts one queue for receives
# (`pings`) and a second for sends (`pongs`).
def pong(pings, pongs)
msg = pings.pop
pongs.push(msg)
end
# Main execution
pings = Queue.new
pongs = Queue.new
Thread.new { ping(pings, "passed message") }
Thread.new { pong(pings, pongs) }
puts pongs.pop
When using queues as method parameters in Ruby, we don’t have the same level of compile-time type safety as in some other languages. However, we can still design our methods to clearly indicate their intended use (send-only or receive-only) through naming conventions and documentation.
In this example:
- We define a
ping
method that only sends a message to a queue. - We define a
pong
method that receives a message from one queue and sends it to another. - In the main execution, we create two queues,
pings
andpongs
. - We use
Thread.new
to create new threads for ourping
andpong
operations, simulating concurrent execution. - Finally, we print the message received from the
pongs
queue.
To run the program:
$ ruby channel_directions.rb
passed message
This example demonstrates how to use Ruby’s Thread and Queue classes to achieve behavior similar to channel directions in other languages. While Ruby doesn’t have built-in concepts like send-only or receive-only channels, we can still design our code to respect these patterns.