0

Can I have a reference to an array cell in Ruby? In C++, I can do something like:

int& ref = arr[x][y];

and later work with the variable ref without the need of typing the whole arr[x][y].

I want to do this as I need to access one and the same cell multiple times throughout a function (I'm doing memoization) and typing unnecessary indexes may only lead to errors.

yasen
  • 1,250
  • 7
  • 13
  • is the goal that the ref will continue to point to the actual data of `arr[x][y]` at any given time, or just store what the value of it was at the time that block of code was written? – Anthony Sep 11 '14 at 16:48
  • @Anthony The former. I simply want to use `ref` instead of the lenghty and error-prone `arr[x][y]`. – yasen Sep 11 '14 at 16:49

4 Answers4

1

All values in ruby are references, so this is certainly possible, but with some important limitations. One caveat is that ruby doesn't DIRECTLY support multidimensional arrays, but you can implement one as an array of arrays or as a hash keyed by tuples.

You can achieve this in cases where the value at (x, y) has already been set by assigning to the value at the given coordinates. If no value currently exists at that location, then you must initialize that value before you can have a reference to it:

# if x and y are indices and a is your "multidimensional array"

a[x][y] = 'First Value'  # Initial value at (x, y)

ref = a[x][y]  # take a reference to the value referenced by a[x][y]

ref.gsub! 'First', 'Second'

a[x][y]  # => 'Second Value'

Keep in mind that the assignment operator in ruby generally means "make the reference on the left side refer to the value on the right". This means that if you use the assignment operator on your reference, then you're actually making it refer to a new value:

a[x][y] = 1     # Initialize value with 1
ref = a[x][y]   # Take the reference

ref += 1        # Assignment    
ref             # => 2
a[x][y]         # => 1

You might have better success by using a Hash and keying the hash with tuples of your coordinates, and then using these tuples to get references to specific locations:

a = {}
loc = [x, y]

a[loc] = 'First Value'     # Initial value
a[[x,y]]  # => 'First Value'

a[loc] = 'Second Value'  # Assignment
a[[x,y]]  # => 'Second Value'

a[loc] = 1  # Assignment
a[loc] += 1 # Assignment
a[[x,y]]  # => '2'
Iron Savior
  • 4,238
  • 3
  • 25
  • 30
0

Ruby is considered pass by value so to answer your question (not pass by reference like C++), it's not directly possible to do what you're asking.

There's a really good post in this answer by Abe that you should read through:

Is Ruby pass by reference or by value?

Community
  • 1
  • 1
Anthony
  • 15,435
  • 4
  • 39
  • 69
  • It's easy to misunderstand if you only say that ruby is "pass by value". While this is true, it's crucial to also understand that every value (not just variables, but all values) in ruby is a reference. – Iron Savior Sep 11 '14 at 18:22
0

For ref to continue to point to the actual data of arr[x][y] at any given time, one possibiliy is to write it as a method :

def ref
  ar[1][1]
end
steenslag
  • 79,051
  • 16
  • 138
  • 171
0

In a high level language like ruby, all variables are references and there is no "pointers" or levels of indirections like C or C++, you should create objects to hold this references to get similar behavior

This is what I would do on ruby

Suppose you need to save a "pointer" to a ruby array, then you create a Class to access the array in a given index (there is no such thing like getting a "pointer" to a value in ruby)

class ArrayPointer
  def initialize(array, index)
    @array = array
    @index = index
  end

  def read
    @array[index]
  end

  def write(value)
    @array[index] = value
  end
end

Then, you use the clase this way

array = [1, 2, 3]
pointer = ArrayPointer.new(array, 1)

pointer.write(20)
puts array # [1, 20, 3]

You also can get "pointers" to local variables, but is too weird and uncommon in ruby world and it almost doesn't make sense

Note this kind of code is weird and not common in ruby, but it is interesting from the didactic point of view to compare two great languages like Ruby and C

In the Object Oriented nature of ruby, is preferable to design good abstractions (e.g. instead of using an array to represent your data, if preferable to define a class with methods like the ruby way) before only using elemental structures such as Array or Hash to represent the data used by your program (the last approach common in C, is not the ruby way)

dseminara
  • 11,665
  • 2
  • 20
  • 22