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
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
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.
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.
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
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.
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!