I cannot understand RSPEC2 03_iteration.rb

I am trying to understand yield but I have no clue how to run it on an array. If there is some knowledge out there please help. This works to organise the array but how would I call a block on it I don’t understand. It only yields to the first instance in the array and trying to use splat isn’t helping.

def bubble_sort!()
org = self

until org == self.sort
  i = 0
  j = 1

  while j < org.length
    if org[j] > org[i]
      org[i], org[j] = org[j], org[i]
    elsif org[i] > org[j]
      org[i], org[j] = org[j], org[i]
      i += 1
      j += 1
    end
  end

end

p org

if block_given?
  yield(org)
else
  org
end

end

I was also stuck on this one for a bit.

You will need to add the optional block/proc in as an argument.

def bubble_sort!(&block)

Consider making a ‘default proc’ that the method will use if no block/proc is given.

The proc (default or given) should be called during the sorting.

I’m still stuck. It doesn’t make a difference whether or not I yield with or without an argument.

I am now getting the error:

Array#bubble_sort! will use a block if given
Failure/Error: num22 <=> num12
NoMethodError:
undefined method **' for nil:NilClass # ./spec/03_iteration_spec.rb:75:inblock (4 levels) in <top (required)>’
# ./lib/03_iteration.rb:74:in bubble_sort!' # ./spec/03_iteration_spec.rb:73:inblock (3 levels) in <top (required)>’

def bubble_sort!(&block)
org = self

until org == self.sort
i = 0
j = 1

  while j < org.length
    if org[j] > org[i]
      org[i], org[j] = org[j], org[i]
    elsif org[i] > org[j]
      org[i], org[j] = org[j], org[i]
      i += 1
      j += 1
    end
  end

end

p org

if block_given?
  i = 0
  while i < org.length
    yield(org[i], org[i + 1])
    i += 1
  end
  org
else
  org
end

end

Blocks can be confusing in Ruby. There’s two things you need to know. We use yield if we want to run the code in a block that we didn’t explicitly specify when we defined the method. So, if we just said def method_name instead of def method_name(&blk), then we would use yield. However, if we did say def method_name(&blk), we can run the code in blk by saying blk.call. Either way, we can pass in one or more argument to yield or blk.call if the block expects arguments.

Does this help?

Sorry it didn’t help telling me that information. For some reason the block will not run correctly at all and is giving me a ‘can’t compare nil with **’ so I just refactored it.

BBCode

class Array
def bubble_sort!(&prc)
prc ||= Proc.new {|x,y| x<=>y}

sorted = false
until sorted
  sorted = true

  self.each_index do |idx|
    next if self.length - 1 == idx

    nidx = idx + 1

    if prc.call(self[idx], self[nidx]) == 1
      sorted = false
      self[idx], self[nidx] = self[nidx], self[idx]
    end
  end
end
self

end

def bubble_sort(&prc)
self.dup.bubble_sort!(&prc)
end
end

That new code looks good!

One thing I like about it is that there is only one chunk of logic to keep track of, regardless of whether a proc gets passed or not, because of that slick use of the ||= operator on the third line to declare a default proc. This means that your code is much easier to debug, as it’s always using the same basic logic.

Let us know if you have any further questions, Jay.

-Shalin
Hacker in Residence, NYC

I was deferred to the July cohort. I don’t know how to understand the alpha course any better than I already did. Is there any way to get more help besides taking up all of the office hours time?

Office hours, live chat, and this forum are all here to help you as much as you need. Don’t hesitate to come to office hours with your questions, we’re there for you!

Also, at office hours, talk with your fellow students! They are your single biggest resources, and we really cultivate an atmosphere where everybody helps everybody else-- teaching is one of the best ways to solidify your own understanding!

Looking closely at the solutions can also help you get un-stuck. My favorite way to use the solutions was to look at them if stuck for > half hour on something, understand why the solution is doing what it does, and then to re-implement WITHOUT LOOKING directly at the solution or copying verbatim to cement my understanding.

Please don’t hesitate to ask any further questions, the more specific the better!

Shalin
Hacker in Residence, NYC