myself
myself

Reputation: 405

How does a block variable change with a nested array?

I am following a tutorial.

arr = [["cow", "moo"], ["duck", "quack"]]
bucket = arr[0]
bucket.each_with_index do |kv, i|
  k, v = kv
  puts k
  puts v
end

I understand that when it goes through arr[0], it is first kv = cow and i = 0, and then kv = moo and i = 1. How does k, v = kv make sense? To me, it seems that k = kv and v = kv, but that isn't the case. I don't understand the purpose.

Upvotes: 1

Views: 50

Answers (2)

tadman
tadman

Reputation: 211750

What's happening here is it's breaking out the key/value pair variable kv into two separate variables k and v. You'll need to adjust your code to look like this:

arr = [["cow", "moo"], ["duck", "quack"]]
arr.each_with_index do |kv, i|
  k, v = kv
  puts k
  puts v
end

What's happening here is demonstrated by this:

kv = [ :key, :value ]

# Assign k to the first value, v to the second in kv
k, v = kv

k
# => :key
v
# => :value

A less messy way of doing this break-out is this:

arr.each_with_index do |(k, v), i|
  # ... Use k and v normally
end

That notation allows you to expand the array into separate variables in advance of using them. It's a trick that comes in handy when dealing with value pairs of this sort.

It's worth noting you wouldn't have to do this if you didn't use each_with_index, as each is sufficient here since that index value is never used:

each do |k, v|
  # ...
end

Upvotes: 0

Cyzanfar
Cyzanfar

Reputation: 7146

Basically the line k, v = kv means that you are assigning kv to k or k= kv

comma separated assignment is just another way of assigning multiple variables in one line, it's just syntactic sugar.

Try messing around with your code and do something like this for example:

    arr = [["cow", "moo"], ["duck", "quack"]]
    bucket = arr[0]
    bucket.each_with_index do |kv, i|
      k, v = kv, i
      puts "k is #{k} and v is #{v}"
    end
   # k is cow and v is 0
   # k is moo and v is 1

Upvotes: 1

Related Questions