lib/more_math/ranking_common.rb
module MoreMath module RankingCommon # Returns the size of this instance's collection, a Fixnum. attr_reader :size # Returns the rank of this instance, a Fixnum in the range # of 0 and #last. attr_reader :rank # Returns the rank of the last ranked instance. attr_reader :last # Returns the collection the #rank applies to if any was set, otherwise # retrurns nil. attr_reader :collection # Switches this instance to the next ranked instance. If this was the #last # instance it wraps around the first (<code>rank == 0</code>) instance. def next! self.rank += 1 self end alias succ! next! # Returns the next ranked instance. If this instance is the #last instance # it returns the first (<code>rank == 0</code>) instance again. def next clone.next! end alias succ next # Switches this instance to the previously ranked instance. If this was the # first instance it returns the last (<code>rank == #last</code>) instance. def pred! self.rank -= 1 self end # Returns the previously ranked instance. If this was the first instance it # returns the last (<code>rank == #last</code>) instance. def pred clone.pred! end # Switches this instance to a randomly ranked instance. def random! new_rank = rand(last + 1).to_i self.rank = new_rank self end # Returns a randomly ranked instance. def random clone.random! end # Iterates over all instances starting with the # first (<code>rank == 0</code>) ranked instance and ending with the # last (<code>rank == #last</code>) ranked instance while # yielding to a freshly created instance for every iteration # step. # # The mixed in methods from the Enumerable module rely on this method. def each # :yields: perm 0.upto(last) do |r| klon = clone klon.rank = r yield klon end self end # Does something similar to #each. It doesn't create new # instances (less overhead) for every iteration step, but yields to a # modified self instead. This is useful if one only wants to call a # method on the yielded value and work with the result of this call. It's # not a good idea to put the yielded values in a data structure because all # of them will reference the same (this!) instance. If you want to do this # use #each. def each! old_rank = rank 0.upto(last) do |r| self.rank = r yield self end self ensure self.rank = old_rank end end end