Parent

Files

LazyList

Constants

Identity

Identity lambda expression, mostly used as a default.

All

This block returns true.

Tuple

Create an array tuple from argument list.

LessThan

Returns true, if a less than b.

SwapTuple

Swaps you and me and returns an Array tuple of both.

VERSION

LazyList version

Attributes

cached[W]

Set this to false, if index references into the lazy list shouldn’t be cached for fast access (while spending some memory on this). This value defaults to true.

head[W]

Returns the value of this element.

tail[W]

Writes a tail value.

Public Class Methods

[](a, n = nil) click to toggle source

Returns a lazy list which is generated from the Enumerable a or LazyList.span(a, n), if n was given as an argument.

# File lib/lazylist.rb, line 189
  def self.[](a, n = nil)
    case
    when n
      span(a, n)
    when a.respond_to?(:to_io)
      io(a.to_io)
    when a.respond_to?(:to_ary)
      from_queue(a.to_ary)
    when Range === a
      from_range(a)
    when a.respond_to?(:each)
      from_enum(a)
    else
      list(a)
    end
  end
const_missing(id) click to toggle source

If the constant Empty is requested return a new empty list object.

# File lib/lazylist.rb, line 134
  def self.const_missing(id)
    if id == :Empty
      new(nil, nil)
    else
      super
    end
  end
empty() click to toggle source

Returns an empty list.

# File lib/lazylist.rb, line 94
  def self.empty
    new(nil, nil)
  end
from(n = 0) click to toggle source

Returns a list of all elements succeeding n (that is created by calling the succ method) and starting from n.

# File lib/lazylist.rb, line 259
  def self.from(n = 0)
    tabulate(n)
  end
from_enum(e) click to toggle source

Generates a lazy list from any data structure e which responds to the each method.

# File lib/lazylist.rb, line 208
  def self.from_enum(e)
    from_queue ReadQueue.new(e)
  end
from_queue(rq) click to toggle source

Generates a lazyx list by popping elements from a queue.

# File lib/lazylist.rb, line 213
  def self.from_queue(rq)
    return empty if rq.empty?
    new(delay { rq.shift }) { from_queue(rq) }
  end
from_range(r) click to toggle source

Generates a lazy list from a Range instance r.

# File lib/lazylist.rb, line 219
  def self.from_range(r)
    if r.exclude_end?
      if r.begin >= r.end
        empty
      else
        new(delay { r.begin }) { from_range(r.begin.succ...r.end) }
      end
    else
      case
      when r.begin > r.end
        empty
      when r.begin == r.end
        new(delay { r.begin }) { empty }
      else
        new(delay { r.begin }) { from_range(r.begin.succ..r.end) }
      end
    end
  end
io(input, &f) click to toggle source

Generates a lazy list of a give IO-object using a given block or Proc object to read from this object.

# File lib/lazylist.rb, line 271
  def self.io(input, &f)
    if f
      input.eof? ? empty : new(delay { f[input] }) { io(input, &f) }
    else
      input.eof? ? empty : new(delay { input.readline }) { io(input) }
    end
  end
iterate(i = 0, &f) click to toggle source

Generates a lazy list which iterates over its previous values computing something like: f(i), f(f(i)), f(f(f(i))), …

# File lib/lazylist.rb, line 265
  def self.iterate(i = 0, &f)
    new(delay { i }) { iterate(f[i], &f) }
  end
new(head = nil, tail = nil, &block) click to toggle source

Creates a new LazyList element. The tail can be given either as second argument or as block.

# File lib/lazylist.rb, line 106
  def initialize(head = nil, tail = nil, &block)
    @cached = true
    @ref_cache = {}
    if tail
      if block
        raise LazyList::Exception,
          "Use block xor second argument for constructor"
      end
      @head, @tail = head, tail
    elsif block
      @head, @tail = head, delay(&block)
    else
      @head, @tail = nil, nil
    end
  end
span(a, n) click to toggle source

Generates a finite lazy list beginning with element a and spanning n elements. The data structure members have to support the successor method succ.

# File lib/lazylist.rb, line 241
  def self.span(a, n)
    if n > 0
      new(delay { a }) { span(a.succ, n - 1) }
    else
      empty
    end
  end
tabulate(n = 0, &f) click to toggle source

Generates a lazy list which tabulates every element beginning with n and succeding with succ by calling the Proc object f or the given block. If none is given the identity function is computed instead.

# File lib/lazylist.rb, line 252
  def self.tabulate(n = 0, &f)
    f = Identity unless f
    new(delay { f[n] }) { tabulate(n.succ, &f) }
  end

Public Instance Methods

*(other, &block) click to toggle source

Alias for product

+(*other) click to toggle source

Alias for append

==(other) click to toggle source

Alias for eql?

[](n, m = nil) click to toggle source

If n is a Range every element in this range is returned. If n isn’t a Range object the element at index n is returned. If m is given the next m elements beginning the n-th element are returned.

# File lib/lazylist.rb, line 344
  def [](n, m = nil)
    case
    when Range === n
      sublist(n)
    when n < 0
      nil
    when m
      sublist(n, m)
    else
      ref(n).head
    end
  end
append(*other) click to toggle source

Append this lazy list to the _*other_ lists, creating a new lists that consists of the elements of this list and the elements of the lists other1, other2, … If any of the lists is infinite, the elements of the following lists will never occur in the result list.

# File lib/lazylist.rb, line 421
  def append(*other)
    if empty?
      if other.empty?
        empty
      else
        other.first.append(*other[1..-1])
      end
    else
      self.class.new(delay { head }) { tail.append(*other) }
    end
  end
Also aliased as: +
cached?() click to toggle source

Returns true, if index references into the lazy list are cached for fast access to the referenced elements.

# File lib/lazylist.rb, line 129
  def cached?
    !!@cached
  end
cartesian_product(*others) click to toggle source

Returns the cartesian_product of this LazyList and the others as a LazyList of Array tuples. A block can be given to yield to all the created tuples and create a LazyList out of the block results.

# File lib/lazylist.rb, line 585
  def cartesian_product(*others) # :yields: tuple
    case
    when empty?
      self
    when others.empty?
      block_given? ? map(&Proc.new) : map
    else
      product = others[1..-1].inject(product(others[0])) do |intermediate, list| 
        intermediate.product(list) do |existing, new_element|
          existing + [ new_element ]
        end
      end
      if block_given?
        block = Proc.new
        product.map { |tuple| block[*tuple] }
      else
        product
      end
    end
  end
drop(n = 1) click to toggle source

Drops the next n elements and returns the rest of this lazy list. n defaults to 1.

# File lib/lazylist.rb, line 467
  def drop(n = 1)
    each(n) { }
  end
drop!(n = 1) click to toggle source

Drops the next n elements, destroys them in the lazy list and returns the rest of this lazy list. Also see each! .

# File lib/lazylist.rb, line 473
  def drop!(n = 1)
    each!(n) { }
  end
each(n = nil) click to toggle source

Iterates over all elements. If n is given only n iterations are done. If self is a finite lazy list each returns also if there are no more elements to iterate over.

# File lib/lazylist.rb, line 360
  def each(n = nil)
    s = self
    if n
      until n <= 0 or s.empty?
        yield s.head
        s = s.tail
        n -= 1 unless n.nil?
      end
    else
      until s.empty?
        yield s.head
        s = s.tail
      end
    end
    s
  end
each!(n = nil) click to toggle source

Similar to LazyList#each but destroys elements from past iterations perhaps saving some memory. Try to call GC.start from time to time in your block.

# File lib/lazylist.rb, line 379
  def each!(n = nil)
    s = self
    if n
      until n <= 0 or s.empty?
        yield s.head
        s = s.tail
        n -= 1 unless n.nil?
        @head, @tail = s.head, s.tail
      end
    else
      until s.empty?
        yield s.head
        s = s.tail
        @head, @tail = s.head, s.tail
      end
    end
    self
  end
empty() click to toggle source

Returns an empty list.

# File lib/lazylist.rb, line 99
  def empty
    @klass ||= self.class
    @klass.new(nil, nil)
  end
empty?() click to toggle source

Returns true if this is the empty lazy list.

# File lib/lazylist.rb, line 492
  def empty?
    self.peek_head == nil && self.peek_tail == nil
  end
eql?(other) click to toggle source

Returns true, if this lazy list and the other lazy list consist of only equal elements. This is only sensible, if the lazy lists are finite and you can spare the memory.

# File lib/lazylist.rb, line 499
  def eql?(other)
    other.is_a? self.class or return false
    size == other.size or return false
    to_a.zip(other.to_a) { |x, y| x == y or return false }
    true
  end
Also aliased as: ==
first(n = 1) click to toggle source

Alias for take

half_product(other, &block) click to toggle source

Returns one “half” of the product of this LazyList and the other:

 list(1,2,3).half_product(list(1,2)).to_a # => [[1, 1], [2, 1], [2, 2], [3, 1], [3, 2]]

block can be used to yield to every pair generated and create a new list element out of it. It defaults to Tuple.

# File lib/lazylist.rb, line 542
  def half_product(other, &block)
    block ||= Tuple
    if empty? or other.empty?
      empty
    else
      mix(
        delay { zip(other, &block) },
        delay { tail.half_product(other, &block) }
      )
    end
  end
head() click to toggle source

Returns the head of this list by computing its value.

# File lib/lazylist.rb, line 147
  def head
    @head = force @head
  end
inspect() click to toggle source

Inspects the list as far as it has been computed by returning a string of the form [1, 2, 3,… ].

# File lib/lazylist.rb, line 509
  def inspect
    return '[]' if empty?
    result = '['
    first = true
    s = self
    seen = {}
    until s.empty? or Promise === s.peek_head or seen[s.__id__]
      seen[s.__id__] = true
      if first
        first = false
      else
        result << ', '
      end
      result << s.head.inspect
      Promise === s.peek_tail and break
      s = s.tail
    end
    unless empty?
      if first
        result << '... '
      elsif !s.empty?
        result << ',... '
      end
    end
    result << ']'
  end
Also aliased as: to_s
last(n = 1) click to toggle source

Return the last n elements of the lazy list. This is only sensible if the lazy list is finite of course.

# File lib/lazylist.rb, line 479
  def last(n = 1)
    to_a.last n
  end
length() click to toggle source

Alias for size

merge(other, &compare) click to toggle source

Merges this lazy list with the other. It uses the &compare block to decide which elements to place first in the result lazy list. If no compare block is given lambda { |a,b| a < b } is used as a default value.

# File lib/lazylist.rb, line 401
  def merge(other, &compare)
    compare ||= LessThan
    case
    when empty?
      other
    when other.empty?
      self
    when compare[head, other.head]
      self.class.new(head) { tail.merge(other, &compare) }
    when compare[other.head, head]
      self.class.new(other.head) { merge(other.tail, &compare) }
    else
      self.class.new(head) { tail.merge(other.tail, &compare) }
    end
  end
product(other, &block) click to toggle source

Returns the (cartesian) product of this LazyList instance and the other. block can be used to yield to every pair generated and create a new list element out of it, but it’s useful to at least return the default Tuple from the block.

# File lib/lazylist.rb, line 563
  def product(other, &block)
    if empty? or other.empty?
      empty
    else
      other_block =
        if block
          swap block
        else
          block = Tuple
          SwapTuple
        end
      mix(
        delay { half_product(other, &block)},
        delay { other.tail.half_product(self, &other_block) }
      )
    end
  end
Also aliased as: *
size() click to toggle source

Returns the size. This is only sensible if the lazy list is finite of course.

# File lib/lazylist.rb, line 485
  def size
    inject(0) { |s,| s += 1 }
  end
Also aliased as: length
sublist(n, m = nil) click to toggle source

Returns the result of sublist_range(n), if n is a Range. The result of sublist_span(n, m), if otherwise.

# File lib/lazylist.rb, line 307
  def sublist(n, m = nil)
    if n.is_a? Range
      sublist_range(n)
    else
      sublist_span(n, m)
    end
  end
sublist_range(range) click to toggle source

Returns the sublist, constructed from the Range range indexed elements, of this lazy list.

# File lib/lazylist.rb, line 281
  def sublist_range(range)
    f = range.first
    l = range.exclude_end? ? range.last - 1 : range.last
    sublist_span(f, l - f + 1)
  end
sublist_span(n, m = nil) click to toggle source

Returns the sublist, that spans m elements starting from the n-th element of this lazy list, if m was given. If m is nonĀ­positive, the empty lazy list LazyList::Empty is returned.

If m wasn’t given returns the n long sublist starting from the first (index = 0) element. If n is nonĀ­positive, the empty lazy list LazyList::Empty is returned.

# File lib/lazylist.rb, line 294
  def sublist_span(n, m = nil)
    if not m
      sublist_span(0, n)
    elsif m > 0
      l = ref(n)
      self.class.new(delay { l.head }) { l.tail.sublist_span(0, m - 1) }
    else
      empty
    end
  end
tail() click to toggle source

Returns the next element by computing its value if necessary.

# File lib/lazylist.rb, line 162
  def tail
    @tail = force @tail
  end
take(n = 1) click to toggle source

Takes the next n elements and returns them as an array.

# File lib/lazylist.rb, line 436
  def take(n = 1)
    result = []
    each(n) { |x| result << x }
    result
  end
Also aliased as: first
take!(n = 1) click to toggle source

Takes the next n elements and returns them as an array. It destroys these elements in this lazy list. Also see each! .

# File lib/lazylist.rb, line 459
  def take!(n = 1)
    result = []
    each!(n) { |x| result << x }
    result
  end
take_range(range) click to toggle source

Takes the range indexes of elements from this lazylist and returns them as an array.

# File lib/lazylist.rb, line 446
  def take_range(range) 
    range.map { |i| ref(i).head }
  end
take_span(n, m) click to toggle source

Takes the m elements starting at index n of this lazy list and returns them as an array.

# File lib/lazylist.rb, line 452
  def take_span(n, m)
    s = ref(n)
    s ? s.take(m) : nil
  end
to_s() click to toggle source

Alias for inspect

Protected Instance Methods

peek_head() click to toggle source

Returns the head of this list without forcing it.

# File lib/lazylist.rb, line 152
  def peek_head
    @head
  end
peek_tail() click to toggle source

Returns the tail of this list without forcing it.

# File lib/lazylist.rb, line 167
  def peek_tail
    @tail
  end
ref(n) click to toggle source

Returns the n-th LazyList-Object.

# File lib/lazylist.rb, line 322
  def ref(n)
    if @ref_cache.key?(n)
      return @ref_cache[n]
    end
    s = self
    i = n
    while i > 0 do
      if s.empty?
        return set_ref(n, self)
      end
      s.head # force the head
      s = s.tail
      i -= 1
    end
    set_ref(n, s)
  end

Private Instance Methods

set_ref(n, value) click to toggle source

(Not documented)

# File lib/lazylist.rb, line 315
  def set_ref(n, value)
    return value unless cached?
    @ref_cache[n] = value
  end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.