Pointers in Ruby

Ruby doesn’t have explicit pointers like Go, but we can demonstrate similar concepts using object references and mutable objects.

# We'll show how object references work in contrast to values with
# 2 methods: `zeroval` and `zeroref`. `zeroval` takes a number
# argument, so it will be passed by value. `zeroval` will get a copy
# of `ival` distinct from the one in the calling method.

def zeroval(ival)
  ival = 0
end

# `zeroref` takes an array as an argument. In Ruby, arrays are mutable
# objects, so when we pass an array to a method, we're passing a reference
# to that array. Changes made to the array inside the method will affect
# the original array.

def zeroref(iref)
  iref[0] = 0
end

# Main program
i = 1
puts "initial: #{i}"

zeroval(i)
puts "zeroval: #{i}"

# We create an array with a single element to simulate a mutable integer
i_array = [i]
zeroref(i_array)
puts "zeroref: #{i_array[0]}"

# In Ruby, we can print the object_id, which is similar to a memory address
puts "object_id: #{i.object_id}"
$ ruby pointers.rb
initial: 1
zeroval: 1
zeroref: 0
object_id: 3

In this Ruby version, zeroval doesn’t change the i in the main program, but zeroref does because it has a reference to the mutable array that contains our value.

Ruby uses object references instead of pointers. When you pass an object to a method, you’re passing a reference to that object. For immutable objects like numbers, this behaves like pass-by-value. For mutable objects like arrays, it behaves more like pass-by-reference.

The object_id in Ruby is somewhat analogous to a memory address in languages with explicit pointers. It’s a unique identifier for each object, but it’s not a direct memory address that you can manipulate like in lower-level languages.

This example demonstrates how Ruby handles value types and reference types differently, which is conceptually similar to the distinction between values and pointers in languages like Go.