pinkfloyd90
pinkfloyd90

Reputation: 688

Confusion accessing array values vs array position

Say we have the following code:

def run(input)
  start = 0
  lap = 0

  while true
    opcode = input[start]
    input1 = input[start + 1]
    input2 = input[start + 2]
    output = input[start + 3]

    if opcode == 1
      input[output] = input[input1] + input[input2]
    elsif opcode == 2
      input[output] = input[input1] * input[input2]
    elsif opcode == 99
      puts "breaking"
      break
    else
      puts "CANT RECOGNIZE THAT OPCODE"
    end
    start += 4
    lap += 1
  end
  puts input
  puts "finished after #{lap} loops"
end

input = [1,9,10,3,2,3,11,0,99,30,40,50]
run(input)

I understand why printing input1 I get the number stored in that possition in the array (9), but I don't get why printing input[input1] (input[input[start + 1]]) accesses the value the number in that position (9) points to (30).

The code works for the exercise but I don't understand why.

Upvotes: 1

Views: 51

Answers (1)

tadman
tadman

Reputation: 211740

Each time you call Array#[] you're doing a look-up, and if you nest these then you get an index-based "pointer" to another value. This is common in some data structures as it can store one copy of a value that's used in multiple places, among other things. One example in common use is DNS, as per RFC1035.

In your example it's easier to understand when you consider the order of operations. Ruby, like many languages, evaluates from the inside out, or in other words:

a = [ 1, 2, 3 ]

a[a[1]]
# => 3

Where that's evaluated as if it were expressed as:

x = a[1]
# => 2
a[x]
# => 3

There's no limit on the number of times you can nest an index resolution like this provided none of the indexes exceed the array bounds, as a[1234] returns nil, and a[nil] is an error. You can theoretically do this indefinitely, though in practice you'd rarely do it more than a handful of times.

Upvotes: 3

Related Questions