# Honey nut loops # # Ruby of course supports 'for' for i in ['a','b','c'] puts i end # And has the usual loop control for i in [1,2,3,4,5,6,7,8,9] # Skip to next iteration next if i % 2 == 0 puts "For #{i}" # Redo this iteration redo if i == 3 && (red ||= true) != red # Break out of the loop break if i == 7 end # For is just really syntactic sugar for [1,2,3].each do |i| next if i % 2 == 0 puts "Each #{i}" end # Ruby also gives us a basic manually-controlled loop i = 0 loop do puts "Loop #{i}" break if (i += 1) > 2 end # Groovy's 'times' syntax is mostly stolen from Ruby 3.times { puts "A time" } # The block takes an arg, so we can pass in the index as a param. 3.times { |i| puts "Time #{i}" } # We also have proper language structures for looping def to_six(i) while (i < 6) print "to_six #{i}" print (i += 1) < 6 ? ", " : "\n" end end to_six(4) to_six(2) i = 0 begin puts i += 1 end until i == 6 # Though of course Ruby already supports this, 0.upto(6) do |i| puts i end # The range operator (..) is used here - NOTE that it DOESNT go in square # brackets - there is no 'tuple' type in Ruby, so that would make us a # single-element array with a Range inside. Instead, we just use the # syntax (poss with parens): (0..5).each do | i | print "Range: i is ", i, "\n" end ########################### # Ruby supports a *lot* of these kinds of iterators, and in fact they're # probably the cornerstone of a lot of Ruby's coolest stuff. For example, # 'inject' allows you to inject an accumulator into your loops. The # return from the block becomes the accumulator for the next iteration. # The traditional example: def isum(from) sum = [1,2,3].inject(from) do |acc, i| acc + i end end puts "Sum from 0: #{isum(0)}" puts "Sum from 10: #{isum(10)}" # I've found that another generally useful inject is (remember that # '<<' appends the right-hand side to the array on the left. family = ["Ross","Rosie","Jake"].inject([]) { | ary, it | ary << "#{it} Randall-Bamford" } # Let's use 'inspect' to have the array shown like ["...", "..."] rather # than being automatically joined. puts family.inspect # Note that an alternative way to get the above is with: # # p family # # 'p' uses inspect, rather than to_s as with puts. # For a good heads-up on what's available, check out the 'Enumerable' # module in RI.