module RandomReadable

RandomReadable mixin provides non-destructive methods of Array. The class must provide one or more methods from read-accessor group ([], at, read_access). The class may provide one size-provider (size, length). read_access(pos) is similar to “at” method, but the module guarantees the argument is positive. And if the class provides size or length methods, the argument is less than size or length. If the class does not provide size-provider, some of the methods of the module raises NotImplementedError. Please see the document of each method.

Public Instance Methods

&(other) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 41
def &(other)
  delegate_to_array(:&, other)
end
*(arg) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 49
def *(arg)
  delegate_to_array(:*, arg)
end
+(other) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 57
def +(other)
  delegate_to_array(:+, other)
end
-(other) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 65
def -(other)
  delegate_to_array(:-, other)
end
<=>(other) click to toggle source

Same as Array’s. This method evaluates elements needed to get results. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 73
def <=>(other)
  min_size = [size, other.size].min
  min_size.times do |i|
    res = self[i] <=> other[i]
    return res if res != 0
  end
  return size <=> other.size
end
==(other) click to toggle source

Same as Array’s if the class provides size method. Same as Object’s if not. This method evaluates elements needed to get results.

Calls superclass method
# File lib/random-readable.rb, line 85
def ==(other)
  return super unless has_size?
  return false if size != other.size
  size.times do |i|
    return false if self[i] != other[i]
  end

  return true
end
[](*args) click to toggle source

This method is a read-accessor (see README). If you overrides this method, provide same function as Array’s. Same as Array’s. If the argument is one Integer, this method evaluates one element. If the argument is a Range or start/length, this method evaluates elements in the Range or start/length. This method raises NotImplementedError if the class provides neither size nor length method, and the argument is minus.

# File lib/random-readable.rb, line 103
def [](*args)
  if args.size >= 3 || args.size == 0
    raise ArgumentError, "wrong number of arguments (#{args.size} for 1..2)"
  end

  if args.size == 2
    start = args[0].to_int
    len   = args[1].to_int
    if has_size?
      return nil if start < -size || size < start
      return nil if len < 0
      res = []
      len.times do |i|
        res << at(start + i) if start + i < size
      end
      return res
    else
      if len < 0
        return []
      else
        return Array.new(len) do |i|
          at(start + i)
        end
      end
    end
  elsif args[0].is_a? Range
    range = args[0]
    first = range.first
    last = range.last

    if has_size?
      first += size if first < 0
      last += size if last < 0
      last -= 1 if range.exclude_end?
      if first == size || (first == 0 && last < 0)
        return []
      elsif first < 0 || size < first
        return nil
      end
      res = []
      (first..last).each do |i|
        res << at(i) if 0 <= i && i < size
      end
      return res
    else
      range.map do |i|
        at(i)
      end
    end
  else
    at(args[0])
  end
end
Also aliased as: slice
assoc(key) click to toggle source

Same as Array’s. This method sequentially evaluates the elements. Note that this method loops infinitely if the class provides neither size nor lenght method.

# File lib/random-readable.rb, line 161
def assoc(key)
  enum = has_size? ? :each : :cycle
  send(enum) do |el|
    if el.respond_to?(:[]) && !el.empty? && el[0] == key
      return el
    end
  end
  return nil
end
at(pos) click to toggle source

This method is a read-accessor (see README). If you overrides this method, provide same function as Array’s. Same as Array’s. This method evaluates one element. even if the argument is minus or out-of-range.

# File lib/random-readable.rb, line 176
def at(pos)
  pos = pos.to_int

  if 0 <= pos && !has_size?
    return read_access(pos)
  elsif 0 <= pos && pos < size
    return read_access(pos)
  elsif -size <= pos && pos < 0
    return read_access(size + pos)
  else
    return nil
  end
end
combination(n, &block) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 196
def combination(n, &block)
  delegate_to_array(:combination, n, &block)
end
compact() click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 204
def compact
  res = []
  each do |el|
    res << el unless el.nil?
  end
  return res
end
cycle() { |at(i)| ... } click to toggle source

Same as Array’s. This method sequentially evaluates the elements of the class.

Calls superclass method
# File lib/random-readable.rb, line 214
def cycle
  if has_size?
    super
  else
    i = 0
    loop do
      yield at(i)
      i += 1
    end
  end
end
each(&block) click to toggle source

Same as Array’s. This method sequentially evaluates the elements of the class. This method or the Enumerator raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 230
def each(&block)
  if block.nil?
    return Enumerator.new(self, :each)
  else
    size.times do |i|
      block.call(self[i])
    end
    return self
  end
end
eql?(other) click to toggle source

if the object provides size or length, this method is same as Array’s and evaluates minimum elements needed to get results. If not, this method is same as Object’s and evaluates no element.

Calls superclass method
# File lib/random-readable.rb, line 244
def eql?(other)
  return false unless other.is_a?(RandomReadable)
  return super(other) unless has_size?

  begin
    return false if other.size != size
  rescue NotImplementedError
    return false
  end

  each_index do |i|
    return false unless at(i).eql?(other.at(i))
  end

  return true
end
fetch(nth, *args, &block) click to toggle source

Same as Array’s. If the argument is an index, this method evaluates one element. If the argument is start/length, this method evaluates elements between the start/length. This method does not accept a minus index if the class provides neither size nor length method.

# File lib/random-readable.rb, line 267
def fetch(nth, *args, &block)
  if args.size >= 2
    raise ArgumentError, "wrong number of arguments (#{args.size + 1} for 1..2)"
  end

  if has_size? && (nth < -size || size <= nth)
    if block != nil
      # TODO: Warn if ifnone value is present.
      return block.call
    elsif args.size == 1
      return args[0]
    else
      raise IndexError,
            "index #{nth} outsize of the random readable object " \
            "bounds: #{-size}...#{size}"
    end
  else
    return at(nth)
  end
end
first(*args) click to toggle source

Same as Array’s. If the argument is an index, this method evaluates one element. If the argument is start/length, this method evaluates elements between the start/length.

# File lib/random-readable.rb, line 292
def first(*args)
  if args.size >= 2
    raise ArgumentError, "wrong number of arguments (#{args.size + 1} for 1..2)"
  end

  if args.size == 1
    width = args[0]
    width = [width, size].min if has_size?

    return self[0...width]
  else
    return at(0)
  end
end
flatten(lv = nil) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 311
def flatten(lv = nil)
  delegate_to_array(:flatten, lv)
end
hash() click to toggle source

Same as Array’s and evaluates all elements of the class if the class provides size or length method. Same as Object’s if not.

Calls superclass method
# File lib/random-readable.rb, line 318
def hash
  return super unless has_size?

  res = 0
  each do |el|
    res += el.hash
  end
  return res
end
include?(val = nil, &block) click to toggle source
# File lib/random-readable.rb, line 328
def include?(val = nil, &block)
  !!index(val, &block)
end
index(val = nil, &block) click to toggle source

Same as Array’s. This method evaluates the elements sequentially. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 336
def index(val = nil, &block)
  # needs size
  if block.nil?
    each_with_index do |el, index|
      return index if el == val
    end
  else
    each_with_index do |el, index|
      return index if block.call(el)
    end
  end
  return nil
end
inspect() click to toggle source

Same as Array’s and evaluates all elements of the class if the class provides size or length method. Same as Object’s if not.

Calls superclass method
# File lib/random-readable.rb, line 364
def inspect
  return super unless has_size?

  to_ary.inspect
end
join(sep = $,) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 374
def join(sep = $,)
  to_ary.join(sep)
end
last(n = nil) click to toggle source

Same as Array’s. This method evaluates minimum elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 382
def last(n = nil)
  if n.nil?
    return at(size - 1)
  else
    n = size if n > size
    return Array.new(n) do |i|
      at(size - n + i)
    end
  end
end
pack(template) click to toggle source

Same as Array’s. This method evaluates all elements of the class. (TODO: Stop evaluating unnecessary elelments) This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 398
def pack(template)
  delegate_to_array(:pack, template)
end
permutation(n, &block) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 406
def permutation(n, &block)
  delegate_to_array(:permutation, n, &block)
end
product(*lists, &block) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 414
def product(*lists, &block)
  delegate_to_array(:product, *lists, &block)
end
rassoc(obj) click to toggle source

Same as Array’s. This method evaluates minimum elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 422
def rassoc(obj)
  each do |el|
    if el.respond_to?(:[]) && el.size >= 2 && el[1] == obj
      return el
    end
  end
  return nil
end
repeated_combination(n, &block) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 435
def repeated_combination(n, &block)
  delegate_to_array(:repeated_combination, n, &block)
end
repeated_permutation(n, &block) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 443
def repeated_permutation(n, &block)
  delegate_to_array(:repeated_permutation, n, &block)
end
reverse() click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 451
def reverse
  delegate_to_array(:reverse)
end
reverse_each() { |at(i)| ... } click to toggle source

Same as Array’s. This method evaluates elements of the class sequentially. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 459
def reverse_each(&block)
  # Needs size.
  if block.nil?
    return Enumerator.new(self, :reverse_each)
  else
    (size - 1).downto 0 do |i|
      yield at(i)
    end
  end
end
rindex(val = nil, &block) click to toggle source

Same as Array’s. This method evaluates minimum elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 474
def rindex(val = nil, &block)
  i = 0
  if block.nil?
    reverse_each do |el|
      i += 1
      return size - i if el == val
    end
  else
    reverse_each do |el|
      i += 1
      return size - i if block.call(el)
    end
  end
  return nil
end
rotate(cnt = 1) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 494
def rotate(cnt = 1)
  delegate_to_array(:rotate, cnt)
end
sample(*args) click to toggle source

Same as Array’s. This method evaluates one elements of the class if there is no argument. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 502
def sample(*args)
  # Needs size.
  if args.size >= 2
    raise ArgumentError, "wrong number of arguments (#{args.size} for 1..2)"
  end

  if args.size == 1
    n = [args[0].to_int, size].min
    return Enumerator.new do |y|
      each_index do |i|
        if n > 0 && rand(size - i) < n
          y << at(i)
          n -= 1
        end
      end
    end.to_a.shuffle
  else
    if size == 0
      return nil
    else
      return at(rand(size))
    end
  end
end
shuffle() click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 531
def shuffle
  delegate_to_array(:shuffle)
end
slice(*args)
Alias for: []
to_a()
Alias for: to_ary
to_ary() click to toggle source

Returns all elements of the class as an Array. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 24
def to_ary
  Array.new(size) do |i|
    at(i)
  end
end
Also aliased as: to_a
to_s() click to toggle source

Same as Array’s and evaluates all elements of the class if the class provides size or length method. Same as Object’s if not.

Calls superclass method
# File lib/random-readable.rb, line 355
def to_s
  return super unless has_size?

  to_ary.to_s
end
transpose() click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 543
def transpose
  delegate_to_array(:transpose)
end
uniq(&block) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 551
def uniq(&block)
  delegate_to_array(:uniq, &block)
end
values_at(*selectors) click to toggle source

Same as Array’s. This method evaluates minimum elements of the class. The arguments must not be negative values if the class does not provide size or length method.

# File lib/random-readable.rb, line 559
def values_at(*selectors)
  res = []
  selectors.each do |s|
    if s.is_a? Range
      subary = self[s]
      unless subary.nil?
        self[s].each do |el|
          res << el
        end
      end
      if has_size? && !s.exclude_end? && s.include?(size)
        res << nil
      end
    else
      res << self[s.to_int]
    end
  end
  return res
end
zip(*lists, &block) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 583
def zip(*lists, &block)
  delegate_to_array(:zip, *lists, &block)
end
|(other) click to toggle source

Same as Array’s. This method evaluates all elements of the class. This method raises NotImplementedError if the class provides neither size nor length method.

# File lib/random-readable.rb, line 591
def |(other)
  delegate_to_array(:|, other)
end

Private Instance Methods

delegate_to_array(name, *args, &block) click to toggle source
# File lib/random-readable.rb, line 32
def delegate_to_array(name, *args, &block)
  to_ary.send(name, *args, &block)
end