+
+ # This method returns a given element from the array, deleting it from the
+ # array itself. The method returns nil if the element couldn't be found.
+ #
+ # If nil is specified, a random element is returned and deleted.
+ #
+ def delete_one(val=nil)
+ return nil if self.empty?
+ if val.nil?
+ index = rand(self.length)
+ else
+ index = self.index(val)
+ return nil unless index
+ end
+ self.delete_at(index)
+ end
+
+ # This method deletes a given object _el_ if it's found at the given
+ # position _pos_. The position can be either an integer or a range.
+ def delete_if_at(el, pos)
+ idx = self.index(el)
+ if pos === idx
+ self.delete_at(idx)
+ else
+ nil
+ end
+ end
+
+ # Taken from Ruby backports:
+ # shuffle and shuffle! are defined in Ruby >= 1.8.7
+
+ # This method returns a new array with the
+ # same items as the receiver, but shuffled
+ def shuffle
+ dup.shuffle!
+ end unless method_defined? :shuffle
+
+ def shuffle!
+ size.times do |i|
+ r = i + Kernel.rand(size - i)
+ self[i], self[r] = self[r], self[i]
+ end
+ self
+ end unless method_defined? :shuffle!
+end
+
+module ::Enumerable
+ # This method is an advanced version of #join
+ # allowing fine control of separators:
+ #
+ # [1,2,3].conjoin(', ', ' and ')
+ # => "1, 2 and 3
+ #
+ # [1,2,3,4].conjoin{ |i, a, b| i % 2 == 0 ? '.' : '-' }
+ # => "1.2-3.4"
+ #
+ # Code lifted from the ruby facets project:
+ # <http://facets.rubyforge.org>
+ # git-rev: c8b7395255b977d3c7de268ff563e3c5bc7f1441
+ # file: lib/core/facets/array/conjoin.rb
+ def conjoin(*args, &block)
+ num = count - 1
+
+ return first.to_s if num < 1
+
+ sep = []
+
+ if block_given?
+ num.times do |i|
+ sep << yield(i, *slice(i, 2))
+ end
+ else
+ options = (Hash === args.last) ? args.pop : {}
+ separator = args.shift || ""
+ options[-1] = args.shift unless args.empty?
+
+ sep = [separator] * num
+
+ if options.key?(:last)
+ options[-1] = options.delete(:last)
+ end
+ options[-1] ||= _(" and ")
+
+ options.each{ |i, s| sep[i] = s }
+ end
+
+ zip(sep).join
+ end
+end
+
+# Extensions to the Range class
+#
+class ::Range
+
+ # This method returns a random number between the lower and upper bound
+ #
+ def pick_one
+ len = self.last - self.first
+ len += 1 unless self.exclude_end?
+ self.first + Kernel::rand(len)
+ end
+ alias :rand :pick_one
+end
+
+# Extensions for the Numeric classes
+#
+class ::Numeric
+
+ # This method forces a real number to be not more than a given positive
+ # number or not less than a given positive number, or between two any given
+ # numbers
+ #
+ def clip(left,right=0)
+ raise ArgumentError unless left.kind_of?(Numeric) and right.kind_of?(Numeric)
+ l = [left,right].min
+ u = [left,right].max
+ return l if self < l
+ return u if self > u
+ return self
+ end