BrainLikeADullPencil
BrainLikeADullPencil

Reputation: 11673

ruby: execution order in block

I understand what is happening in this skip_tracks method, however, I never could have written it this way, because I don't understand the rule underlying the behavior in the block. This is the part that's puzzling me

 skip.times { playlist.push playlist.shift}

Is there a rule that it executes right to left, so that the value that's shifted is returned and pushed onto playlist? How does one know the value that's shifted is going to be pushed onto playlist? What's happening inside the block to make this a rule? Can you explain...Also, if this block had been written over multiple lines, playlist.push would have been above playlist.shift, and therefore executed first, but this code requires that the value be shifted before pushed


def skip_tracks(playlist, skip)
  if skip > 0
    skip.times { playlist.push playlist.shift}
  else
    skip.abs.times { playlist.unshift playlist.pop }
  end
  puts playlist
end


playlist = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
skip_tracks(playlist, 2)

Upvotes: 0

Views: 321

Answers (1)

lc.
lc.

Reputation: 116538

Think of push and unshift as functions that take an argument and put the element passed to it into the list; and shift and pop as functions that remove and return an element.

If I write what's happening using c-like function syntax, you get:

playlist.push(playlist.shift())

and

playlist.unshift(playlist.pop())

Therefore it will resolve these function calls from the inside out and you get the behavior you see.

Upvotes: 1

Related Questions